【问题标题】:extending an exposed class using boost python使用 boost python 扩展一个暴露的类
【发布时间】:2013-11-15 14:07:09
【问题描述】:

我想扩展一个已经暴露给 python 的类。例如:

sn-p 1:

class_<DataValueContainer, DataValueContainer::Pointer>( "DataValueContainer" )
    .def( "__len__", &DataValueContainer::Size )
    .def( VariableIndexingPython<DataValueContainer, Variable<std::string> >() )
    .def( VariableIndexingPython<DataValueContainer, Variable<int> >() )
    .def( VariableIndexingPython<DataValueContainer, Variable<double> >() )
    .def( self_ns::str( self ) )
    ;

现在在不同的地方我想扩展python类DataValueContainer,比如:

sn-p 2:

class_<DataValueContainer, DataValueContainer::Pointer>
    .def( VariableIndexingPython<DataValueContainer, Variable<MyObject> >() )

是否可以使用 boost.python 来做到这一点?我想这样做的原因是 sn-p 1 在现有代码的内核中,我犹豫要修改它。

最好的问候

【问题讨论】:

    标签: boost-python


    【解决方案1】:

    据我所知,如果不对 sn-p 1 进行一些小的修改或重新实现 boost::python::class_ 的部分内容,这是不可能的。当 boost::python::class_ 类型的对象被实例化时,类型初始化和注册发生在 Boost.Python 的内部。使用相同类型和参数实例化 class_ 将有效地覆盖之前的类对象。

    在 Python 中,问题类似于重新定义的类型。在下面的示例中,spam 标识符用于一种类型,然后与不同的类型相关联:

    >>> class spam:
    ...     def action1(self): pass
    ... 
    >>> # Redefines spam type.
    ... class spam:
    ...     def action2(self): pass
    ... 
    >>> print hasattr(s, "action1")
    False
    >>> print hasattr(s, "action2")
    True
    

    而不是通过其标识符扩展 spam 类型:

    >>> class spam:
    ...     def action1(self): pass
    ... 
    >>> # Extend spam type.
    ... def action2(s): pass
    ... 
    >>> spam.action2 = action2
    >>> s = spam()
    >>> print hasattr(s, "action1")
    True
    >>> print hasattr(s, "action2")
    True
    

    Boost.Python 示例与 Python 示例相当。在这个 sn-p 中,spam 标识符被修改为指向一个新类型,因为实例化了一个新的 class_ 实例。

    #include <boost/python.hpp>
    
    class spam {};
    void action1(spam& self) {}
    void action2(spam& self) {}
    
    BOOST_PYTHON_MODULE(example)
    {
      typedef boost::python::class_<spam> spam_class_type;
      spam_class_type("spam")
        .def("action1", &action1)
        ;
    
      // Redefines spam type. 
      spam_class_type("spam")
        .def("action2", &action1)
        ;
    }
    

    及其用法:

    >>> import example
    __main__:1: RuntimeWarning: to-Python converter for spam already 
                registered; second conversion method ignored.
    >>> s = example.spam()
    >>> print hasattr(s, "action1")
    False
    >>> print hasattr(s, "action2")
    True
    

    要扩展 Boost.Python 中的类型,只需对同一个 class_ 实例进行操作:

    #include <boost/python.hpp>
    
    class spam {};
    void action1(spam& self) {}
    void action2(spam& self) {}
    
    BOOST_PYTHON_MODULE(example)
    {
      typedef boost::python::class_<spam> spam_class_type;
      spam_class_type spam_ = spam_class_type("spam");
      spam_
        .def("action1", &action1)
        ;
    
      // Extend spam type.
      spam_
        .def("action2", &action2)
        ;
    }
    

    及其用法:

    >>> import example
    >>> s = example.spam()
    >>> print hasattr(s, "action1")
    True
    >>> print hasattr(s, "action2")
    True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      相关资源
      最近更新 更多