[英]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.