提振.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
。最有可能的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);
}
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
已经是第一个宏的一部分。我不确定这是否是您的问题所在,因为在某些时候,挖掘更多的装饰变得非常乏味。
寻找一些装饰器定义时,我偶然发现了坏消息。
相关文章:
- 如何在c++中定义以struct为数据成员的类中的构造函数
- 使用成员在类中创建 lambda 表达式
- 使用静态成员声明类时遇到问题
- 没有公共构造函数作为另一个类模板成员的类模板
- 我们可以通过 IPC 传递具有动态管理成员的类对象吗?
- 具有 STL 向量类型成员的类的复制内存
- 内存中类位置的成员是否取决于类成员在类定义中的位置?
- C++成员变量类Q_PROPERTY QML 中不可用
- 提升 - 类没有名为"序列化"的成员(抽象类)?
- C++ - 移动具有固定大小的 c 样式数组成员的类的构造函数
- 具有未知结构作为成员的类
- 清除具有已删除赋值运算符的成员的类实例
- 简化在 Pybind11 中为 C++ 模板类生成包装类:模板声明不能出现在块范围内
- 错误:请求成员 .. 是非类类型"char"
- 没有成员的类的<运算符
- C++-用与被包装数据相同的语法构造包装类
- 从相同类型的静态成员进行类内初始化
- C++-用和结构相同的语法围绕结构构造包装类
- 成员访问没有运行时指针的包装类
- 提振.Python缓存包装类成员