APy 包装器是临时的,因为 s1, s2 是字符串。一旦创建了s1,Python 并不关心创建它的设置是否也可以用于创建s2。很可能b.a 被丢弃,因为它没有被存储。
当你做类似的事情时会发生同样的事情
a1 = b.a
s1 = a1.str1
s2 = a1.str1
?
更新:
我们正试图找出 b.a 在 Python 中的实际含义。
你的调用是
BOOST_PYTHON_IMPORT(wrapped) {
class_<A, std::shared_ptr<A>>("APy")
.def_readonly("str1", &A::str1);
class_<B>("BPy")
.def_readwrite("a", &B::a);
}
def_readwrite在boost/python/class.hpp中的定义是
template <class D>
self& def_readwrite(char const* name, D const& d, char const* doc=0)
{
return this->def_readwrite_impl(name, d, doc BOOST_PYTHON_DATA_MEMBER_HELPER(D));
}
// translates to
class_<B>& def_readwrite(char const* name, A &d,
char const* doc=0, detail::is_data_member_pointer<B>()){...}
def_readwrite_impl 的最佳匹配实现在哪里
class_<B>& def_readwrite_impl(char const* name, A B::*a,
char const* doc, mpl::true_)
因为B::*a 应该是 B 的成员,而不是函数指针。这反过来又调用了
class_<B>& def_readwrite_impl(char const* name, A B::*pm_, char const* doc, mpl::true_)
pm_ 是指向某个 B 类型对象的成员的未绑定指针。
现在,让我们转到add_property。
class_<B>& add_property(char const* name, A &fget = B::*a,
A &fset = B::*a, char const* docstr = 0)
从这里我们去 boost/python/objects/class.hpp 看看class_base::add_property:
void add_property(char const* name,
object const& fget, object const& fset, char const* docstr);
不幸的是,实现被隐藏了。但签名表明魔法发生在make_getter。
template <class F>
object make_getter(F f)
{
typedef typename api::is_object_operators<F>::type is_obj_or_proxy;
return this->make_fn_impl(
detail::unwrap_wrapper((W*)0)
, f, is_obj_or_proxy(), (char*)0, detail::is_data_member_pointer<F>()
);
}
unwrap_wrapper 没有对指针做任何事情,因为std::shared_ptr 不是从boost::python::wrapper 派生的。
is_data_member_pointer 已经是第一个宏的一部分。我不确定这是否是您案例中的问题,因为在某些时候挖掘更多装饰器变得非常乏味。
在寻找一些装饰器定义时,我偶然发现了坏消息。将其作为评论添加到您的原始问题中。