How Can I Declare A Boost.python C++ Class With Pyobjects
i want to write a c++ class with PyObjects to access them from Python to reference them with an existing Python object instance. In short words i want to store/manage Python object
Solution 1:
When managing Python objects in C++ with Boost.Python, one should consider using the boost::python::object
class rather than PyObject
. The object
acts very much like a Python variables, allowing for Python-ish code in C++. Furthermore, they behave similar to a smart pointer, providing referencing counting and lifetime management, where as one would need to explicitly manage the reference count with a PyObject
.
Here is a complete example based on the original code that demonstrates using boost::python::object
and PyObject
:
#include<boost/python.hpp>/// @brief Mockup type that can manage two Python objects.structvar
{
boost::python::object test_1; // managed
PyObject* test_2; // must explicitly managevar()
: 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.voidvar_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)
;
}
Interactive usage:
>>> classTest:
... 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))
Post a Comment for "How Can I Declare A Boost.python C++ Class With Pyobjects"