簡體   English   中英

boost.python緩存包裹的類成員

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM