我有一个基类和一个派生类,它们都有一个同名的静态方法。在保持名称相同的情况下,是否可以同时公开这两个名称?这将编译,但在导入模块时引发异常
struct Base
{
static std::string say_hi() { return "Hi"; }
};
struct Derived : public Base
{
static std::string say_hi() { return "Hello"; }
};
BOOST_PYTHON_MODULE(HelloBoostPython)
{
namespace py = boost::python;
py::class_<Base>("Base").add_static_property("say_hi", &Base::say_hi);
py::class_<Derived, py::bases<Base>>("Derived").add_static_property("say_hi", &Derived::say_hi);
}
进口时:
>>> import HelloBoostPython
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
SystemError: initialization of HelloBoostPython raised unreported exception
将最后一行更改为其他名称是可行的,但我更希望覆盖基类的属性:
py::class_<Derived, py::bases<Base>>("Derived").add_static_property("say_hello", &Derived::say_hi);
这是可行的,但我得到的是类方法而不是属性:
BOOST_PYTHON_MODULE(HelloBoostPython)
{
namespace py = boost::python;
py::object base = py::class_<Base>("Base");
base.attr("say_hi") = Base::say_hi;
py::object derived = py::class_<Derived, py::bases<Base>>("Derived");
derived.attr("say_hi") = Derived::say_hi;
}
这将为我提供属性,但如果静态方法不是常量,则在一般情况下不起作用:
BOOST_PYTHON_MODULE(HelloBoostPython)
{
namespace py = boost::python;
py::object base = py::class_<Base>("Base");
base.attr("say_hi") = Base::say_hi();
py::object derived = py::class_<Derived, py::bases<Base>>("Derived");
derived.attr("say_hi") = Derived::say_hi();
}
嗯
看看
Boost Python
是如何公开静态属性的,以及它在Python
中的行为,看起来这是Boost Python
中的一个bug当我尝试导入有问题的示例时,出现以下错误:
无法设置该属性,因为派生类中存在冲突
Derived
类首先从Base
继承say_hi
属性,然后尝试定义它自己的属性。这可以通过将Derived
类中的say_hi
更改为say_hello
来轻松验证,正如作者所做的那样:py::class_<Derived, py::bases<Base>>("Derived").add_static_property("say_hello", &Derived::say_hi);
然后我们可以看到以下数据描述符
help(HelloBoostPython.Derived)
:但是,当我们在python中定义类似的内容时:
我们可以看到这里只有
say_hi
中定义的Derived
:从
Derived
中删除say_hi
后:我们从
Base
继承它,然后:问题是,当Boost.Python的元类试图声明和设置
Derived.say_hi
时,它会解析为Base.say_hi.__set__
,因为它是从Base
继承的现有类描述符。一个解决方案是自己将属性绑定到Derived
类。例如这样
say_hi
作为Boost.Python.StaticProperty
实例直接绑定到Derived
类。现在输入以下代码:将正确打印:
相关问题 更多 >
编程相关推荐