gpt4 book ai didi

python - 使用 Boost-Python 包装枚举

转载 作者:太空狗 更新时间:2023-10-30 02:46:45 25 4
gpt4 key购买 nike

我在使用 Boost-Python 包装 Python 枚举时遇到问题。

最初我打算在 try-catch (我已经在下面插入了我的整个代码)语句中做类似下面的事情:

main_namespace["Motion"] = enum_<TestClass::Motion>("Motion")
.value("walk", TestClass::walk)
.value("bike", TestClass::bike)
;

一切正常,编译完成。在运行时我得到了这个错误(这对我来说毫无意义):

AttributeError: 'NoneType' object has no attribute 'Motion'

之后我决定在我的代码中使用 BOOST_PYTHON_MODULE 编写一个 Python 模块。初始化 Python 解释器后,我想立即使用这个模块,但不知道如何使用(?)。以下是我的全部代码:

#include <boost/python.hpp>
#include <iostream>

using namespace std;
using namespace boost::python;

BOOST_PYTHON_MODULE(test)
{
enum_<TestClass::Motion>("Motion")
.value("walk", TestClass::walk)
.value("bike", TestClass::bike)
;
}

int main()
{
Py_Initialize();

try
{
object pyMainModule = import("__main__");
object main_namespace = pyMainModule.attr("__dict__");

//What previously I intended to do
//main_namespace["Motion"] = enum_<TestClass::Motion>("Motion")
// .value("walk", TestClass::walk)
// .value("bike", TestClass::bike)
//;

//I want to use my enum here
//I need something like line below which makes me able to use the enum!

exec("print 'hello world'", main_namespace, main_namespace);
}
catch(error_already_set const&)
{
PyErr_Print();
}

Py_Finalize();
return 0;
}

任何关于在 Python 中包装和使用枚举的有用信息都将不胜感激!提前致谢

最佳答案

AttributeError 是在没有先设置范围的情况下尝试创建 Python 扩展类型的结果。 boost::python::enum_构造函数状态:

Constructs an enum_ object holding a Python extension type derived from int which is named name. The named attribute of the current scope is bound to the new extension type.

嵌入 Python 时,要使用自定义 Python 模块,通常最容易使用 PyImport_AppendInittab ,然后按名称导入模块。

PyImport_AppendInittab("example", &initexample);
...
boost::python::object example = boost::python::import("example");

这是一个完整的示例,显示了通过 Boost.Python 公开的两个枚举。一个包含在由 main 导入的单独模块(example)中,另一个直接暴露在 main 中。

#include <iostream>
#include <boost/python.hpp>

/// @brief Mockup class with a nested enum.
struct TestClass
{
/// @brief Mocked enum.
enum Motion
{
walk,
bike
};

// @brief Mocked enum.
enum Color
{
red,
blue
};
};

/// @brief Python example module.
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::enum_<TestClass::Motion>("Motion")
.value("walk", TestClass::walk)
.value("bike", TestClass::bike)
;
}

int main()
{
PyImport_AppendInittab("example", &initexample); // Add example to built-in.
Py_Initialize(); // Start interpreter.

// Create the __main__ module.
namespace python = boost::python;

try
{
python::object main = python::import("__main__");
python::object main_namespace = main.attr("__dict__");
python::scope scope(main); // Force main scope

// Expose TestClass::Color as Color
python::enum_<TestClass::Color>("Color")
.value("red", TestClass::red)
.value("blue", TestClass::blue)
;

// Print values of Color enumeration.
python::exec(
"print Color.values",
main_namespace, main_namespace);

// Get a handle to the Color enumeration.
python::object color = main_namespace["Color"];
python::object blue = color.attr("blue");

if (TestClass::blue == python::extract<TestClass::Color>(blue))
std::cout << "blue enum values matched." << std::endl;

// Import example module into main namespace.
main_namespace["example"] = python::import("example");

// Print the values of the Motion enumeration.
python::exec(
"print example.Motion.values",
main_namespace, main_namespace);

// Check if the Python enums match the C++ enum values.
if (TestClass::bike == python::extract<TestClass::Motion>(
main_namespace["example"].attr("Motion").attr("bike")))
std::cout << "bike enum values matched." << std::endl;
}
catch (const python::error_already_set&)
{
PyErr_Print();
}
}

输出:

{0: __main__.Color.red, 1: __main__.Color.blue}
blue enum values matched.
{0: example.Motion.walk, 1: example.Motion.bike}
bike enum values matched.

关于python - 使用 Boost-Python 包装枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18930801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com