我有一些boost python类,我在python中实例化。我想复制它们。所以,如果我有
p = Bernoulli(0.5)
我想做
q = Bernoulli(p)
但是,如果我不知道p的类型怎么办?我试着这样做:
q = copy.deepcopy(p)
但是python说它无法腌制p。
我唯一的解决方案是将一个clone()函数添加到Bernoulli的接口中吗?或者我可以以某种方式自动生成该方法吗?可以使copy.deepcopy与Boost.python对象一起使用吗?
答案 0 :(得分:3)
来自http://mail.python.org/pipermail/cplusplus-sig/2009-May/014505.html
#define PYTHON_ERROR(TYPE, REASON) \
{ \
PyErr_SetString(TYPE, REASON); \
throw bp::error_already_set(); \
}
template<class T>
inline PyObject * managingPyObject(T *p)
{
return typename bp::manage_new_object::apply<T *>::type()(p);
}
template<class Copyable>
bp::object
generic__copy__(bp::object copyable)
{
Copyable *newCopyable(new Copyable(bp::extract<const Copyable
&>(copyable)));
bp::object
result(bp::detail::new_reference(managingPyObject(newCopyable)));
bp::extract<bp::dict>(result.attr("__dict__"))().update(
copyable.attr("__dict__"));
return result;
}
template<class Copyable>
bp::object
generic__deepcopy__(bp::object copyable, bp::dict memo)
{
bp::object copyMod = bp::import("copy");
bp::object deepcopy = copyMod.attr("deepcopy");
Copyable *newCopyable(new Copyable(bp::extract<const Copyable
&>(copyable)));
bp::object
result(bp::detail::new_reference(managingPyObject(newCopyable)));
// HACK: copyableId shall be the same as the result of id(copyable)
in Python -
// please tell me that there is a better way! (and which ;-p)
int copyableId = (int)(copyable.ptr());
memo[copyableId] = result;
bp::extract<bp::dict>(result.attr("__dict__"))().update(
deepcopy(bp::extract<bp::dict>(copyable.attr("__dict__"))(),
memo));
return result;
}
使用它:
class_<foo>(foo)
.def("__copy__", &generic__copy__< foo >)
.def("__deepcopy__", &generic__deepcopy__< foo >)
.def(init< const foo & >())
答案 1 :(得分:2)
对于复制,您可以实现__copy__
和__deepcopy__
特殊方法(其中一个可以包装复制构造函数,具体取决于类的C ++复制语义),或者添加{{ 3}}。 copy
模块将使用特殊复制方法(如果可用)和酸洗方法。
以下是使用复制构造函数实现__copy__
的示例:
template<typename T> const T copyObject(const T& v) { return v; }
boost::python::class_<C>("C").def("__copy__", copyObject<C>);
答案 2 :(得分:1)
是的,您可以通过在对象上实现__setstate__
和__getstate__
方法,使boost :: python对象可以深度复制(也可以选择)。
基本上,__getstate__
应返回一个表示对象内部状态的(python)对象,而__setstate__
显然接受所述对象并更新对象的状态。
如果您的对象采用__init__
的参数,您还应该考虑实施__getinitargs__
。
有关详细信息,请参阅Python docs。