如何在 boost::python 中向模块添加属性?
您可以使用 getter 和 setter (在简单的情况下)向类添加属性:
class<X>("X")
.add_property("foo", &X::get_foo, &X::set_foo);
那么您可以像这样从 python 中使用它:
>>> x = mymodule.X()
>>> x.foo = 'aaa'
>>> x.foo
'aaa'
但是如何向模块本身(而不是类)添加属性?
使用上述两种方式添加类
scope().attr("globalAttr") = ??? something ???
我可以
def("globalAttr", ??? something ???);
的全局函数和对象,但似乎无法像在类中那样添加属性。
You can add a property to a class using a getter and a setter (in a simplistic case):
class<X>("X")
.add_property("foo", &X::get_foo, &X::set_foo);
So then you can use it from python like this:
>>> x = mymodule.X()
>>> x.foo = 'aaa'
>>> x.foo
'aaa'
But how to add a property to a module itself (not a class)?
There is
scope().attr("globalAttr") = ??? something ???
and
def("globalAttr", ??? something ???);
I can add global functions and objects of my class using the above two ways, but can't seem to add properties the same way as in classes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
__getattr__
和__setattr__
不会在模块上调用,因此您__getattr__
and__setattr__
aren't called on modules, so you can't do this in ordinary Python without hacks (like storing a class in the module dictionary). Given that, it's very unlikely there's an elegant way to do it in Boost Python either.Python Wiki 上的 boost.python/HowTo有一个将 C++ 对象公开为
BOOST_PYTHON_MODULE
内的模块属性的示例:要在
BOOST_PYTHON_MODULE
之外设置属性,请使用现在您可以在 python 中执行类似的操作
当然,您需要提前注册
my_cpp_object
类(例如,您可以在同一个BOOST_PYTHON_MODULE
调用中执行此操作)并确保 C++ 对象生命周期超过 python 模块的生命周期。您可以使用任何bp::object
而不是包装 C++ 对象。请注意,
BOOST_PYTHON_MODULE
会吞掉异常,因此,如果您犯了错误,您不会收到任何错误指示,并且BOOST_PYTHON_MODULE
生成的函数将立即返回。为了简化这种情况的调试,您可以捕获BOOST_PYTHON_MODULE
内部的异常,或者临时添加一些日志语句作为BOOST_PYTHON_MODULE
的最后一行,以查看是否已达到:boost.python/HowTo on Python Wiki has an example of exposing C++ object as a module attribute inside
BOOST_PYTHON_MODULE
:To set the attribute outside of
BOOST_PYTHON_MODULE
useNow you can do in python something like
Of course, you need to register class of
my_cpp_object
in advance (e.g. you can do this inside the sameBOOST_PYTHON_MODULE
call) and ensure C++ object lifetime exceeds that of the python module. You can use anybp::object
instead of wrapping C++ one.Note that
BOOST_PYTHON_MODULE
swallows exceptions, so if you make a mistake, you don't receive any error indication andBOOST_PYTHON_MODULE
-generated function will just immediately return. To ease debugging of this case you can catch exceptions insideBOOST_PYTHON_MODULE
or temporary add some logging statement as a last line ofBOOST_PYTHON_MODULE
to see that it is reached: