如何使用SWIG为C ++类提供Python __repr __()

时间:2013-02-21 23:05:25

标签: c++ python swig repr

我观察到一种类型

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 ++中定义它们,但无济于事。

我错过了什么?

2 个答案:

答案 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的方式。