我的c ++代码非常简单:
struct A
{
A()
{
this->a = 0;
}
py::int_ a;
};
struct B
{
B() {}
A sa;
};
PYBIND11_MODULE(libdemo_ext, m)
{
py::class_<A>(m, "A", py::dynamic_attr())
.def(py::init<>())
.def_readwrite("a", &A::a);
py::class_<B>(m, "B", py::dynamic_attr())
.def(py::init<>())
.def_readwrite("sa", &B::sa);
}
当我像这样在python中使用它时:
def func(b):
sa = b.sa
sa.pa = 'hello'
b = B()
func(b)
print(b.sa.pa)
结果是:
Traceback (most recent call last):
File "demo.py", line 12, in <module>
print(b.sa.pa)
AttributeError: 'libdemo_ext.A' object has no attribute 'pa'
但是如果我这样使用它:
def func(b):
sa = b.sa
sa.pa = 'hello'
b = B()
sa = b.sa
func(b)
print(b.sa.pa)
这没关系。
我有一个带有dynamic_attr的类和一个带有dynamic_attr的B类和一个对象。 但是我不能通过B来转换A的动态功能。
答案 0 :(得分:0)
pybind11跟踪绑定的对象,如果类型和C ++地址匹配,则重新使用它们。这就是第二种情况起作用的原因。我不知道您要描述的确切用例,但是如果始终将属性添加到函数中,则可以通过将引用与'b'对象的生存期绑定来确保引用保持有效。示例:
def func(b):
b._sa = b.sa
b.sa.pa = 'hello'
或:
def func(b):
sa = b.sa
b.__dict__['sa'] = sa
sa.pa = 'hello'
如果您有许多类型为“ A”的对象,则第二种方法将更有效。