Как добавить свойство в модуль в boost :: python? - PullRequest
10 голосов
/ 29 апреля 2010

Вы можете добавить свойство к классу, используя геттер и сеттер (в упрощенном случае):

class<X>("X")
    .add_property("foo", &X::get_foo, &X::set_foo);

Итак, вы можете использовать его из python так:

>>> x = mymodule.X()
>>> x.foo = 'aaa'
>>> x.foo
'aaa'

Но как добавить свойство к самому модулю (не к классу)?

Есть

scope().attr("globalAttr") = ??? something ???

и

def("globalAttr", ??? something ???);

Я могу добавить глобальные функции и объекты моего класса двумя способами, но не могу добавить свойства так же, как в классах.

Ответы [ 2 ]

2 голосов
/ 01 июля 2013

boost.python / HowTo в Python Wiki есть пример предоставления объекта C ++ в качестве атрибута модуля внутри BOOST_PYTHON_MODULE:

namespace bp = boost::python;
BOOST_PYTHON_MODULE(example)
{
    bp::scope().attr("my_attr") = bp::object(bp::ptr(&my_cpp_object));
}

Чтобы установить атрибут вне BOOST_PYTHON_MODULE, используйте

bp::import("example").attr("my_attr") = bp::object(bp::ptr(&my_cpp_object));

Теперь вы можете делать в Python что-то вроде

from example import my_attr

Конечно, вам нужно заранее зарегистрировать класс my_cpp_object (например, вы можете сделать это внутри одного и того же вызова BOOST_PYTHON_MODULE) и убедиться, что время жизни объекта C ++ превышает время жизни модуля python. Вы можете использовать любой bp::object вместо переноса C ++.

Обратите внимание, что BOOST_PYTHON_MODULE проглатывает исключения, поэтому, если вы допустите ошибку, вы не получите никакого сообщения об ошибке, и сгенерированная BOOST_PYTHON_MODULE функция просто немедленно вернется. Чтобы упростить отладку этого случая, вы можете перехватить исключения внутри BOOST_PYTHON_MODULE или временно добавить несколько операторов записи в качестве последней строки BOOST_PYTHON_MODULE, чтобы увидеть, что они достигнуты:

BOOST_PYTHON_MODULE(example)
{
    bp::scope().attr("my_attr2") = new int(1); // this will compile
    std::cout << "init finished\n"; // OOPS, this line will not be reached
}
2 голосов
/ 29 апреля 2010

__getattr__ и __setattr__ не вызываются для модулей, поэтому вы не можете сделать это в обычном Python без хаков (например, хранения класса в словаре модулей). Учитывая это, очень маловероятно, что есть элегантный способ сделать это и в Boost Python.

...