Как я могу объявить класс C ++ Boost.Python с PyObjects

Я хочу написать класс C ++ с PyObjects для доступа к ним из Python, чтобы ссылаться на них с существующим экземпляром объекта Python. Короче говоря, я хочу хранить / управлять экземплярами объектов Python в классе C ++.

Например:

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 = 0test = Test(2,2)

import Var
newStore = Var
newStore.Test_1 = test

Заранее большое спасибо!

поздравил

Фло

0

Решение

При управлении объектами Python в C ++ с помощью Boost.Python следует рассмотреть возможность использования boost::python::object класс, а не PyObject, object действует очень похоже на переменные Python, позволяя использовать код Python-ish в C ++. Кроме того, они ведут себя подобно интеллектуальному указателю, обеспечивая подсчет ссылок и управление временем жизни, когда необходимо явно управлять счетчиком ссылок с помощью 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))
2

Другие решения


По вопросам рекламы [email protected]