创建 boost-python 嵌套名称空间
我需要用boost python创建一个嵌套的命名空间。
假设我有以下的C++类结构:
namespace a
{
class A{...}
namespace b
{
class B{...}
}
}
显而易见的解决方案是行不通的:
BOOST_PYTHON_MODULE( a ) {
boost::python::class_<a::A>("A")
...
;
BOOST_PYTHON_MODULE(b){
boost::python::class_<a::b::B>("B")
...
;
}
}
这会导致编译时错误:链接规范必须在全局范围内
有没有办法声明类B,使得在Python中可以通过a.b.B
来访问它?
2 个回答
10
使用虚拟类的技巧还不错,但有些限制:
import mylib.a
from mylib.a.b import B
所以,建议使用 PyImport_AddModule()。你可以在下面的文章中找到更完整的示例: Python 扩展模块中的包,作者是 Vadim Macagon。
简单来说:
namespace py = boost::python;
std::string nested_name = py::extract<std::string>(py::scope().attr("__name__") + ".nested");
py::object nested_module(py::handle<>(py::borrowed(PyImport_AddModule(nested_name.c_str()))));
py::scope().attr("nested") = nested_module;
py::scope parent = nested_module;
py::class_<a::A>("A")...
12
你想要的是一个 boost::python::scope。
Python 里没有“命名空间”这个概念,但你可以用一个类来模拟命名空间的功能:
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/scope.hpp>
using namespace boost::python;
namespace a
{
class A{};
namespace b
{
class B{};
}
}
class DummyA{};
class DummyB{};
BOOST_PYTHON_MODULE(mymodule)
{
// Change the current scope
scope a
= class_<DummyA>("a")
;
// Define a class A in the current scope, a
class_<a::A>("A")
//.def("somemethod", &a::A::method)
;
// Change the scope again, a.b:
scope b
= class_<DummyB>("b")
;
class_<a::b::B>("B")
//.def("somemethod", &a::b::B::method)
;
}
然后在 Python 中,你可以这样使用:
#!/usr/bin/env python
import mylib
print mylib.a,
print mylib.a.A
print mylib.a.b
print mylib.a.b.B
所有的 a
、a.A
、a.b
和 a.b.B
实际上都是类,但你可以把 a
和 a.b
当作命名空间来用——而不需要真正去实例化它们。