创建boost-python嵌套命名空间

Dew*_*wfy 6 python boost boost-python

使用boost python我需要创建嵌套的命名空间.

假设我有以下cpp类结构:

namespace a
{
    class A{...}
    namespace b
    {
         class B{...}
    }
}
Run Code Online (Sandbox Code Playgroud)

明显的解决方案不起作用:

BOOST_PYTHON_MODULE( a ) {
    boost::python::class_<a::A>("A")
     ...
    ;
    BOOST_PYTHON_MODULE(b){
        boost::python::class_<a::b::B>("B")
        ...
    ;
    }
}
Run Code Online (Sandbox Code Playgroud)

它会导致编译时错误: linkage specification must be at global scope

有没有办法声明可以从Python访问的B类a.b.B

Jam*_*mes 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)
        ;
}
Run Code Online (Sandbox Code Playgroud)

然后在python中,你有:

#!/usr/bin/env python
import mylib

print mylib.a,
print mylib.a.A
print mylib.a.b
print mylib.a.b.B
Run Code Online (Sandbox Code Playgroud)

所有a,a.A,a.ba.b.B实际上的类,但你可以把aa.b就像命名空间-永不实际上的实例化

  • @robert boost :: python :: scope对象使用RAII,因此添加额外的{}来改变范围对象的生命周期; 当scope对象被销毁时,它会恢复创建它时存在的名称空间. (7认同)

rde*_*pes 10

虚拟类的技巧很好,但不允许:

import mylib.a
from mylib.a.b import B
Run Code Online (Sandbox Code Playgroud)

因此,请使用PyImport_AddModule().您可以在以下文章中找到完整的功能示例:Vadim Macagon的Python扩展模块中的包.

简而言之:

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")...
Run Code Online (Sandbox Code Playgroud)

  • 詹姆斯的上述答案不允许`import mylib.a`这一点非常重要.读者,请注意! (2认同)