[英]How can i declare a Boost.Python C++ Class with PyObjects
我想用 PyObjects 編寫一個 C++ 類,以便從 Python 訪問它們以使用現有的 Python 對象實例引用它們。 簡而言之,我想在 C++ 類中存儲/管理 Python 對象實例。
例如:
struct Var
{
PyObject *Test_1;
PyObject *Test_2;
};
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(Var)
{
class_<Var>("Var", init<std::string>())
.def_readwrite("Test_1", &Var::value)
.def_readwrite("Test_2", &Var::value)
;
}
在 python 中,如果可以使用 Boost.Python,我想這樣做:
class Test:
def __init__(self, a = 0, b = 2):
self.a = 0
self.b = 0
test = Test(2,2)
import Var
newStore = Var
newStore.Test_1 = test
非常感謝您提前!
問候
弗洛
當使用 Boost.Python 在 C++ 中管理 Python 對象時,應該考慮使用boost::python::object
類而不是PyObject
。 該object
行為非常類似於 Python 變量,允許在 C++ 中使用 Python 風格的代碼。 此外,它們的行為類似於智能指針,提供引用計數和生命周期管理,其中需要使用PyObject
顯式管理引用計數。
這是一個基於原始代碼的完整示例,演示了如何使用boost::python::object
和PyObject
:
#include <boost/python.hpp>
/// @brief Mockup type that can manage two Python objects.
struct var
{
boost::python::object test_1; // managed
PyObject* test_2; // must explicitly manage
var()
: test_2(Py_None)
{
Py_INCREF(test_2);
}
~var()
{
Py_DECREF(test_2);
}
};
/// @brief Auxiliary function used to return a non-borrowed reference to
// self.test_2. This is necessary because Boost.Python assumes
// that PyObject* passed from C++ to Python are not borrowed.
PyObject* var_test_2_getter(const var& self)
{
PyObject* object = self.test_2;
Py_INCREF(object);
return object;
}
/// @brief Auxiliary function used to manage the reference count of
/// objects assigned to var.test_2.
void var_test_2_setter(var& self, PyObject* object)
{
Py_DECREF(self.test_2);
self.test_2 = object;
Py_INCREF(self.test_2);
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<var>("Var", python::init<>())
.def_readwrite("Test_1", &var::test_1)
.add_property("Test_2", &var_test_2_getter, &var_test_2_setter)
;
}
互動使用:
>>> class Test:
... def __init__(self, a=0, b=2):
... self.a = a
... self.b = b
...
>>> test = Test(2, 2)
>>> from sys import getrefcount
>>> count = getrefcount(test)
>>> import example
>>> store = example.Var()
>>> store.Test_1 = test
>>> assert(store.Test_1 is test)
>>> assert(count + 1 == getrefcount(test))
>>> assert(store.Test_1.a == 2)
>>> store.Test_1.a = 42
>>> assert(test.a == 42)
>>> store.Test_2 = test
>>> assert(store.Test_2 is test)
>>> assert(count + 2 == getrefcount(test))
>>> assert(count + 2 == getrefcount(store.Test_2))
>>> store.Test_2 = None
>>> assert(count + 1 == getrefcount(test))
>>> store = None
>>> assert(count == getrefcount(test))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.