Как я могу использовать Boost :: Python, чтобы добавить метод в экспортируемый класс без изменения базового класса? - PullRequest
1 голос
/ 28 февраля 2010

У меня есть класс в C ++, который я не могу изменить. Однако этот класс содержит std :: list <> элементов, к которым мне нужно иметь доступ в расширении Python. Поскольку Boost :: Python, похоже, не имеет встроенного преобразования между std :: list и списком Python, я надеялся написать метод на C ++, который мог бы выполнить это преобразование для меня и позже, Я сопоставляю классы C ++ с классами Python, я мог бы присоединить этот метод.

Я бы предпочел, если бы я мог просто вызвать метод, как

baseClassInstance.get_std_list_of_items_as_python_list()

Ответы [ 2 ]

3 голосов
/ 10 ноября 2010

Чтобы ответить на вопрос в более общем виде, вы можете прикрепить любую функцию c ++, имеющую правильную подпись, к экспорту python в объявлении class_

предположим, что класс foo:

struct foo
{
    //class stuff here
}

Вы можете определить свободную функцию, которая принимает ссылку на foo в качестве первого аргумента:

int do_things_to_a_foo(foo& self, int a, std::string b, other_type c)
{
    //Do things to self
}

И экспортируйте это как член foo:

class_<foo>("foo")
   ...
   .def("do_things_to_a_foo", &do_things_to_a_foo)
   ...
   ;
1 голос
/ 04 марта 2010

Boost предоставляет помощник для переноса итераторов, который описан здесь: http://www.boost.org/doc/libs/1_42_0/libs/python/doc/v2/iterator.html

Пример слышит, что конец этой страницы работал для меня, вам просто нужно явно создать конверсию, например:

  class_<std::list<Item> >("ItemList")
    .def("__iter__", iterator<std::list<Item> >());

Чтобы изменить класс C ++ без его изменения, я имею привычку создавать тонкую оболочку, которая подклассов реального класса. Это отличное место для того, чтобы отделить всю грязь, которая делает мои объекты C ++ удобными от Python.

  class Py_BaseClass : public BaseClass {
  public:
    std::list<Item> & py_get_items();
  }
...