【问题标题】:How to add a property to a module in boost::python?如何在 boost::python 中向模块添加属性?
【发布时间】:2011-02-13 16:06:13
【问题描述】:

您可以使用 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 ???);

我可以使用上述两种方式添加我的类的全局函数和对象,但似乎无法像在类中那样添加属性。

【问题讨论】:

    标签: c++ python boost boost-python


    【解决方案1】:

    __getattr____setattr__ 不会在模块上调用,因此您可以在没有 hack 的普通 Python 中使用 can't do this(例如在模块字典中存储一个类)。鉴于此,在 Boost Python 中也不太可能有一种优雅的方式来做到这一点。

    【讨论】:

      【解决方案2】:

      Python Wiki 上的boost.python/HowTo 有一个将 C++ 对象公开为 BOOST_PYTHON_MODULE 内的模块属性的示例:

      namespace bp = boost::python;
      BOOST_PYTHON_MODULE(example)
      {
          bp::scope().attr("my_attr") = bp::object(bp::ptr(&my_cpp_object));
      }
      

      要在BOOST_PYTHON_MODULE 之外设置属性,请使用

      bp::import("example").attr("my_attr") = bp::object(bp::ptr(&my_cpp_object));
      

      现在你可以在 python 中做类似的事情

      from example import my_attr
      

      当然,您需要提前注册my_cpp_object 的类(例如,您可以在同一个BOOST_PYTHON_MODULE 调用中执行此操作)并确保C++ 对象的生命周期超过python 模块的生命周期。您可以使用任何 bp::object 而不是包装 C++ 之一。

      请注意,BOOST_PYTHON_MODULE 会吞下异常,因此如果您犯了错误,您不会收到任何错误指示,BOOST_PYTHON_MODULE-generated 函数将立即返回。为了简化这种情况的调试,您可以在BOOST_PYTHON_MODULE 中捕获异常,或者临时添加一些日志语句作为BOOST_PYTHON_MODULE 的最后一行以查看是否已到达:

      BOOST_PYTHON_MODULE(example)
      {
          bp::scope().attr("my_attr2") = new int(1); // this will compile
          std::cout << "init finished\n"; // OOPS, this line will not be reached
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-06
        • 1970-01-01
        • 2017-07-22
        • 1970-01-01
        • 1970-01-01
        • 2022-07-16
        相关资源
        最近更新 更多