我观察到一种类型
help
在Python repl中,一个得到
Type help() for interactive help, ...
当一种类型
help()
一个人被踢进 help 模式。我很确定这是因为 site._Helper 定义__repr__()
(对于第一个示例)和__call__()
(对于第二个示例)。
我喜欢这种行为(只提示对象和可调用语法),我想对我通过SWIG导出到Python的C ++类做同样的事情。这是我尝试做的一个简单例子
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);
};
当我尝试在我的应用程序中使用此类时,我似乎无法获得我使用 help 看到的行为(下面的输出取自嵌入了Python的C ++应用程序,其中每个输入行通过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.
最后一个 print 显示方法__repr__()
存在,但我无法使用更简单的对象引用或使用repr(tam)
找到它。我也尝试定义__str()__
希望我误解哪些会被调用,但仍然没有运气。
我尝试在接口文件中使用%extend
指令将__str__()
或__repr__()
定义插入SWIG接口定义文件,而不是直接在C ++中定义它们,但无济于事。
我错过了什么?
答案 0 :(得分:3)
正如@flexo在评论中建议的那样,如果您使用-builtin
flag到SWIG代码生成器,repr()
将不会调用您的__repr__
方法。相反,您需要定义适合repr槽的函数。
%feature("python:slot", "tp_repr", functype="reprfunc") HelpMimic::printRepr;
根据HelpMimic :: printRepr必须具有与预期签名(tp_repr in Python docs)匹配的签名 - 它必须返回字符串或unicode对象。另一个警告 - 你不能在多个插槽中放置相同的功能,所以不要试图将它用于tp_str!
答案 1 :(得分:3)
我通常使用%extend功能来避免为特定目标语言量身定制C / C ++。 E.g。
%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
%}
};
在 repr 功能中,您可以基本上调用任何函数并格式化输出以满足您的需要。此外,您可以添加属性并定义它们映射到setter和getter的方式。