Я заметил, что когда один из типов
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 ++, но безрезультатно.
Что мне не хватает?
Как @flexo предложил в комментарии, если вы используете -builtin
флаг к генератору кода SWIG, repr()
не буду звонить вашему __repr__
метод. Вместо этого вам нужно определить функцию, которая помещается в слот repr.
%feature("python:slot", "tp_repr", functype="reprfunc") HelpMimic::printRepr;
Согласно HelpMimic :: printRepr должна иметь подпись, соответствующую ожидаемой подписи (tp_repr в документах Python) — он должен возвращать строку или объект Unicode. Еще одна оговорка — вы не можете поместить одну и ту же функцию в более чем один слот, поэтому не пытайтесь использовать это для tp_str!
Я обычно использую функцию% 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
%}
};
Где ты внутри магнезии Функция может вызывать практически любую функцию и форматировать вывод в соответствии с вашими потребностями. Кроме того, вы можете добавить свойства и определить, как они отображаются на сеттеры и геттеры.