2011-08-31 5 views
14

J'ai une classe C++ avec une énumération à l'intérieur, et je voulais imiter cela avec boost::python, de sorte que je puisse écrire MyClass.value en python. boost::python::class_ n'a pas une méthode enum_, et je cherchais des solutions de contournement.Enum à portée de classe

  1. J'ai d'abord essayé avec lambdas comme

    MyClass{ 
        enum{value1,value2}; 
    }; 
    
    class_<MyClass>("MyClass").add_property("value1",&[](){return value1;}).staticmethod("value1"); 
    

    qui donne l'erreur du compilateur (en get_signature pour add_property). Je sais que je pourrais créer une méthode getter pour chacune des valeurs, mais cela me semble très gênant (en termes de typage).

  2. En utilisant attr:

    auto classObj=class_<MyClass>("MyClass"); 
    classObj.attr("value1")=(int)value1; 
    classObj.attr("value2")=(int)value2; 
    

    mais il ne peut pas être enchaînée comme .def et d'autres méthodes de retour référence à l'instance.

Existe-t-il une solution plus élégante?

+0

En dehors de 'MyClass' vous devrez référencer les valeurs enum comme' MyClass :: value1', bien que je sois hors de mon élément avec des trucs boost-python. –

+0

+1 pour avoir pris la peine de formater correctement. –

Répondre

11

Vous pouvez le faire en utilisant un champ:

#include <boost/python/module.hpp> 
#include <boost/python/class.hpp> 
#include <boost/python/scope.hpp> 
#include <boost/python/enum.hpp> 

namespace bp = boost::python; 

class MyClass{ 
    public: 
     enum MyEnum {value1,value2}; 
}; 

BOOST_PYTHON_MODULE(nestedtest){ 

    bp::scope the_scope 
     = bp::class_<MyClass>("MyClass") 
     ; 

    bp::enum_<MyClass::MyEnum>("MyEnum") 
     .value("value1", MyClass::value1) 
     .value("value2", MyClass::value2) 
     .export_values() 
     ; 
} 

Puis, en python, vos valeurs ENUM sont:

In [8]: nestedtest.MyClass.MyEnum.values 
Out[8]: {0: nestedtest.MyEnum.value1, 1: nestedtest.MyEnum.value2} 

In [9]: nestedtest.MyClass.MyEnum.value1 
Out[9]: nestedtest.MyEnum.value1 

In [10]: nestedtest.MyClass.MyEnum.value2 
Out[10]: nestedtest.MyEnum.value2 

(de ma coquille ipython, j'ai testé cela et tout;)

+0

L'énumération est imbriquée, ce qui n'est pas ce que je veux; il est odieux et moins lisible de taper '.MyEnum' sans valeur ajoutée. – eudoxos

+3

La valeur ajoutée est que si, disons, vos valeurs d'énumération étaient toutes ThingyA ThingyB ThingyC, alors vous les exposez à Python comme Thingy.A Thingy.B Thingy.C. Comme le genre de personne odieuse qui fait campagne contre la pollution de l'espace de noms et le trou d'ozone global associé et tout cela, j'évalue cette fonctionnalité;) – James

+0

C'est une question d'opinion (avec laquelle je ne suis pas d'accord), en tout cas la question pour 'MyClass.value'. – eudoxos