2010-04-29 23 views
9

Usted puede agregar una propiedad a una clase utilizando un getter y setter (en un caso simplista):Cómo agregar una propiedad a un módulo en boost :: python?

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

Entonces se puede usar de pitón de esta manera:

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

Pero cómo agregar una propiedad a un módulo en sí (no una clase)?

Hay

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

y

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

puedo añadir funciones globales y objetos de mi clase utilizando las dos formas anteriores, pero parece que no puede agregar propiedades de la misma manera que en clases.

Respuesta

2

__getattr__ y __setattr__ no se llaman en los módulos, por lo que can't do this en Python ordinario sin hacks (como el almacenamiento de una clase en el diccionario del módulo). Teniendo eso en cuenta, es muy poco probable que haya una forma elegante de hacerlo en Boost Python tampoco.

2

boost.python/HowTo en Python wiki tiene un ejemplo de la exposición de objetos C++ como un atributo de un módulo en BOOST_PYTHON_MODULE:

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

para establecer el atributo fuera del BOOST_PYTHON_MODULE uso

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

Ahora se puede hacer en pitón algo así como

from example import my_attr 

Por supuesto, debe registrar la clase de my_cpp_object por adelantado (p. puede hacer esto dentro de la misma llamada a BOOST_PYTHON_MODULE) y asegurarse de que el tiempo de vida de los objetos de C++ excede el del módulo de python. Puede usar cualquier bp::object en lugar de envolver C++ uno.

Tenga en cuenta que BOOST_PYTHON_MODULE se traga excepciones, por lo que si comete un error, no recibe ninguna indicación de error y la función generada BOOST_PYTHON_MODULE volverá inmediatamente. Para facilitar la depuración de este caso, puede capturar las excepciones dentro BOOST_PYTHON_MODULE temporal o añadir alguna declaración de registro como última línea de BOOST_PYTHON_MODULE para ver que se alcanza:

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 
} 
Cuestiones relacionadas