[英]boost.python caching wrapped class members
我有一个琐碎的类依赖:
class A {
... // constructor is omitted
public:
const std::string str1;
};
class B {
public:
std::shared_ptr<A> a;
}
BOOST_PYTHON_IMPORT(wrapped) {
class_<A, std::shared_ptr<A>>("APy")
.def_readonly("str1", &A::str1);
class_<B>("BPy")
.def_readwrite("a", &B::a);
}
在Python中
import wrapped as wr
b = wr.BPy()
s1 = b.a.str1 // APy wrapper created
s2 = b.a.str1 // new APy wrapper created even though object is the same
是否有某种方法可以一次为对象创建此APy包装器? 特别是因为内部对象A是不可变的(在这种情况下)。 否则,创建大量此类临时对象会产生相当大的开销。
APy
包装器是临时的,因为s1, s2
是字符串。 创建s1
,Python不会在乎创建它的设置是否也可以用于创建s2
。 ba
很可能因为未存储而被丢弃。 当您做类似的事情时也会发生同样的事情吗
a1 = b.a
s1 = a1.str1
s2 = a1.str1
?
更新:
我们正在尝试找出Python中的ba到底是什么。
您的调用是
BOOST_PYTHON_IMPORT(wrapped) {
class_<A, std::shared_ptr<A>>("APy")
.def_readonly("str1", &A::str1);
class_<B>("BPy")
.def_readwrite("a", &B::a);
}
在boost/python/class.hpp
中def_readwrite
的定义是
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
已经是第一个宏的一部分。 我不确定这是否是您的坏处,因为在某个时候挖掘更多的装饰器真的很乏味。
在寻找一些装饰器定义时,我偶然发现了一个坏消息。 将其添加为对原始问题的评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.