[英]Wrapping Enums using Boost-Python
我在使用Boost-Python包裝Enum for Python時遇到了問題。
(I've inserted my whole code below) statement: 最初我打算在 (我在下面插入我的整個代碼)聲明中執行以下操作:
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中包裝和使用Enums將不勝感激! 提前致謝
AttributeError
是在沒有首先設置范圍的情況下嘗試創建Python擴展類型的結果。 boost::python::enum_
構造函數指出:
構造一個
enum_
對象,其中包含一個派生自int
的Python擴展類型,名為name
。 當前作用域的name
d屬性綁定到新擴展類型。
嵌入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.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.