2 votes

Comment fournir une valeur d'enum par défaut avec pybind11 ?

Je veux que les fonctions acceptent les paramètres par défaut des enums.

Mais je n'ai pas trouvé la bonne façon de fournir des valeurs par défaut pour les enums dans PyBind11. exemple d'énumération et la documentation, par exemple :

struct Pet
{
    enum Kind
    {
        Dog = 0,
        Cat
    };

    Pet(const std::string &name) : name(name)
    {
    }

    void setName(const std::string &name_)
    {
        name = name_;
    }

    const std::string &getName() const
    {
        return name;
    }

    Kind test(Kind kind = Dog)
    {
        if(kind == Dog)
           std::cout << "Dog" << std::endl;

        if(kind == Cat)
           std::cout << "Cat" << std::endl;

        return kind;
    }

    std::string name;
};

PYBIND11_MODULE(pet,m)
{
    py::class_<Pet> pet(m, "Pet");
    pet.def(py::init<const std::string &>())
       .def("setName", &Pet::setName)
       .def("getName", &Pet::getName)
       .def("test", &Pet::test, py::arg("kind") = Pet::Kind::Dog)
       .def("__repr__", [](const Pet &a) { return "<example.Pet named '" + a.name + "'>"; }
    );

    py::enum_<Pet::Kind>(pet, "Kind")
        .value("Dog", Pet::Kind::Dog)
        .value("Cat", Pet::Kind::Cat)
        .export_values();

Mais ça ne marche pas :

py::arg("kind") = Pet::Kind::Dog 

Lorsque je l'exécute en Python, j'obtiens des erreurs.

from pet import Pet as p
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: arg(): could not convert default argument into a Python object (type not registered yet?). Compile in debug mode for more information.

J'obtiens des erreurs lorsque j'essaie de l'initialiser avec une valeur de chaîne, par exemple "Dog" ou à 1.

3voto

Wim Lavrijsen Points 2353

C'est un simple problème d'ordre : au chargement, les instructions de la définition du module sont exécutées pour créer les classes, les fonctions, etc. de Python. Ainsi, définir Kind d'abord (du côté de Python, bien sûr) pour permettre à l'interpréteur de le trouver lors de la définition des valeurs par défaut lorsqu'il définit test plus tard. C'est-à-dire, utilisez cet ordre :

PYBIND11_MODULE(pet,m)
{
    py::class_<Pet> pet(m, "Pet");

    py::enum_<Pet::Kind>(pet, "Kind")
        .value("Dog", Pet::Kind::Dog)
        .value("Cat", Pet::Kind::Cat)
        .export_values();

    pet.def(py::init<const std::string &>())
       .def("setName", &Pet::setName)
       .def("getName", &Pet::getName)
       .def("test", &Pet::test, py::arg("kind") = Pet::Kind::Dog)
       .def("__repr__", [](const Pet &a) { return "<example.Pet named '" + a.name + "'>"; }
    );

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X