4

いくつかのブーストPythonクラスがあり、Pythonでインスタンス化します。それらをコピーしたい。だから、私が持っている場合

p = Bernoulli(0.5)

私はやってみたいです

q = Bernoulli(p)

しかし、pのタイプがわからない場合はどうなりますか?私はこれをやろうとしました:

q = copy.deepcopy(p)

しかし、Pythonはpを漬けることができないと言いました。

Is my only solution to add a clone() function to the interface of Bernoulli? Or can I have that method automatically generated somehow? Can copy.deepcopy be made to work with Boost.python objects?

4

3 に答える 3

4

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 & >())
于 2011-01-15T23:19:47.217 に答える
2

__copy__コピーの場合は、特別なメソッドと特別なメソッドを実装するか__deepcopy__(クラスのC ++コピーセマンティクスに応じて、そのうちの1つでコピーコンストラクターをラップすることができます)、またはピクルスサポートを追加できます。モジュールは、copy利用可能な場合は特別なコピー方法を使用し、そうでない場合はピクルス方法を使用します。

コピーコンストラクタを使用して実装する例を次に示します__copy__

template<typename T> const T copyObject(const T& v) { return v; }
boost::python::class_<C>("C").def("__copy__", copyObject<C>);
于 2011-01-14T23:40:59.103 に答える
1

__setstate__はい、オブジェクトにメソッドと メソッドを実装することで、boost :: pythonオブジェクトをディープコピー可能(および選択可能)にすることができ __getstate__ます。

基本的に、__getstate__オブジェクトの内部状態を表す(python)オブジェクトを返す必要がありますが、__setstate__明らかにそのオブジェクトを受け入れて、オブジェクトの状態を更新します。

オブジェクトがの引数を取る場合は__init__、の実装も検討する必要があります__getinitargs__

詳細については、Pythonのドキュメントを参照してください。

于 2011-01-14T23:24:08.660 に答える