Как дать классу C ++ Python __repr __ () с помощью SWIG

Я заметил, что когда один из типов

help

в Python Repl, каждый получает

Type help() for interactive help, ...

и когда один печатает

help()

кого-то пинают Помогите Режим. Я уверен, что это потому, что site._Helper определяет __repr__() (для первого примера) и __call__() (для второго).

Мне нравится это поведение (запрашивает только объект и вызываемый синтаксис), и я хотел бы сделать то же самое для класса C ++, который я экспортирую в Python через SWIG. Вот простой пример того, что я пытался сделать

helpMimic.h
-----------
class HelpMimic
{
public:
HelpMimic() {};
~HelpMimic() {};

char *__repr__();
void operator()(const char *func=NULL);
};

helpMimic.cxx
-------------
char *HelpMimic::__repr__()
{
return "Online help facilities are not yet implemented.";
}

void HelpMimic::operator()(const char *func)
{
log4cxx::LoggerPtr transcriptPtr = oap::getTranscript();
std::string commentMsg("# Online help facilities are not yet implemented. Cannot look up ");
if (func) {
commentMsg += func;
}
else {
commentMsg += "anything.";
}

LOG4CXX_INFO(transcriptPtr, commentMsg);
}

helpMimic.i
-----------
%module sample
%{
#include <helpMimic.h>
%}
class HelpMimic
{
public:
HelpMimic() {};
~HelpMimic() {};

char *__repr__();
void operator()(const char *func=NULL);
};

Когда я пытаюсь использовать этот класс в своем приложении, я не могу получить поведение, которое вижу Помогите (вывод ниже взят из приложения C ++ со встроенным Python, где каждая строка ввода отправляется через PyEval_String()):

 tam = sample.HelpMimic()
tam   # echoes 'tam', nothing else
print tam
# _5010b70200000000_p_HelpMimic
print repr(tam)
# <Swig Object of type 'HelpMimic *' at 0x28230a0>
print tam.__repr__()
# Online help facilities are not yet implemented.

Что в прошлом Распечатать показывает, что метод __repr__() есть, но я не могу найти его, используя более простую ссылку на объект или используя repr(tam), Я также попытался определить __str()__ в надежде, что я неправильно понял, что будет вызвано, но все равно не повезло.

Я пытался использовать %extend директива в файле интерфейса для вставки __str__() или __repr__() определение в файл определения интерфейса SWIG, вместо определения их непосредственно в C ++, но безрезультатно.

Что мне не хватает?

8

Решение

Как @flexo предложил в комментарии, если вы используете -builtin флаг к генератору кода SWIG, repr() не буду звонить вашему __repr__ метод. Вместо этого вам нужно определить функцию, которая помещается в слот repr.

%feature("python:slot", "tp_repr", functype="reprfunc") HelpMimic::printRepr;

Согласно HelpMimic :: printRepr должна иметь подпись, соответствующую ожидаемой подписи (tp_repr в документах Python) — он должен возвращать строку или объект Unicode. Еще одна оговорка — вы не можете поместить одну и ту же функцию в более чем один слот, поэтому не пытайтесь использовать это для tp_str!

3

Другие решения

Я обычно использую функцию% extension, чтобы избежать адаптации C / C ++ к конкретному целевому языку. Например.

%extend MyClass {
%pythoncode %{
def __repr__(self):
# How you want your object to be shown
__swig_getmethods__["someMember"] = SomeMemberGet
__swig_setmethods__["someMember"] = SomeMemberSet
if _newclass:
someMember = property(SomeMemberGet,SomeMemberSet)
def show(self):
# You could possibly visualize your object using matplotlib
%}
};

Где ты внутри магнезии Функция может вызывать практически любую функцию и форматировать вывод в соответствии с вашими потребностями. Кроме того, вы можете добавить свойства и определить, как они отображаются на сеттеры и геттеры.

3

По вопросам рекламы [email protected]