2010-04-29 16 views
9

Vous pouvez ajouter une propriété à une classe à l'aide d'un getter et un setter (dans un cas simpliste):Comment ajouter une propriété à un module dans boost :: python?

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

Alors vous pouvez l'utiliser de python comme ceci:

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

Mais comment ajouter une propriété à un module lui-même (pas une classe)?

Il est

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

et

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

je peux ajouter des fonctions globales et des objets de ma classe en utilisant les deux méthodes ci-dessus, mais ne peut pas sembler ajouter des propriétés de la même manière que dans les classes.

Répondre

2

__getattr__ et __setattr__ ne sont pas appelés sur les modules, donc vous can't do this en Python ordinaire sans hacks (comme le stockage d'une classe dans le dictionnaire du module). Compte tenu de cela, il est très peu probable qu'il existe une façon élégante de le faire dans Boost Python.

2

boost.python/HowTo sur Python Wiki a un exemple d'exposer l'objet de C comme un attribut de module à l'intérieur BOOST_PYTHON_MODULE:

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

Pour définir l'attribut en dehors de BOOST_PYTHON_MODULE utilisation

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

Maintenant, vous pouvez le faire en python quelque chose comme

from example import my_attr 

Bien sûr, vous devez enregistrer la classe my_cpp_object à l'avance (par ex. vous pouvez le faire dans le même appel BOOST_PYTHON_MODULE) et assurez-vous que la durée de vie de l'objet C++ dépasse celle du module python. Vous pouvez utiliser n'importe quel bp::object au lieu d'envelopper un C++.

Notez que BOOST_PYTHON_MODULE avale des exceptions, donc si vous faites une erreur, vous ne recevez aucune indication d'erreur et BOOST_PYTHON_MODULE -generated function retournera immédiatement. Pour faciliter la mise au point de ce cas, vous pouvez prendre des exceptions à l'intérieur BOOST_PYTHON_MODULE ou temporaire ajouter une déclaration d'enregistrement en tant que dernière ligne de BOOST_PYTHON_MODULE pour voir qu'il est atteint:

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 
}