繁体   English   中英

使用SWIG打印包装为Python的C ++类时,不会调用__str __()

[英]__str__() not called when printing C++ class wrapped for Python with SWIG

我正在尝试使用SWIG打印我为Python包装的C ++类。 我已经按照文档和这个问题: 如何在python中对swig矩阵对象进行stringfy

扩展的__str__函数在那里,但是当我从Python打印对象时它不会被调用。 让我举一个最小的例子:

TestClass.h

#include <iostream> 

class TestClass{
private:
    int my_int;
public:
    TestClass():
        my_int(0)
    {}

    friend std::ostream& operator<< (std::ostream& o, TestClass const& t){
        o<< "TestClass: " << t.my_int;
        return o;
    }
};

TestClass.cpp

#include "TestClass.h"

int main(){
    using namespace std;
    TestClass t;
    cout << t << endl;
}

TestClass.i

%define __STR__() \
const char* __str__() { 
  std::cout << *$self << std::endl;
  std::ostringstream out; 
  out << *$self; \
  return out.str().c_str(); 
}

const char* __unicode__() { 
  std::cout << "unicode: " << *$self << std::endl;
  std::ostringstream out; 
  out << *$self; \
  return out.str().c_str(); 
}
%enddef

%extend TestClass{
    __STR__()
};

的CMakeLists.txt

cmake_minimum_required (VERSION 2.6)
project (battery_lib_cpp)
set(CMAKE_VERBOSE_MAKEFILE 1)

FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
SET(CMAKE_SWIG_FLAGS "-Wall")

#look for Pythonlibs
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})

SET_SOURCE_FILES_PROPERTIES(TestClass.i PROPERTIES CPLUSPLUS ON)
SET_PROPERTY(SOURCE TestClass.i PROPERTY SWIG_FLAGS "-builtin")

SWIG_ADD_MODULE(TestClass python TestClass.i TestClass.cpp)

在构建(cmake。,make)之后,我得到以下内容:

matthias@rp3deb:~/dvl/swig_str_minimal$ python
Python 2.7.8 (default, Jul 26 2014, 15:25:14) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import TestClass
>>> t = TestClass.TestClass()
>>> print t
<Swig Object of type 'TestClass *' at 0x7f1dffcb2b90>
>>> print t.__str__()
TestClass: 0
TestClass: 0
>>> print t.__str__
<built-in method __str__ of TestClass object at 0x7f1dffcb2b90>

__unicode__()另一个测试

>>> import TestClass
>>> t = TestClass.TestClass()
>>> print str(t)
<Swig Object of type 'TestClass *' at 0x7f6584ae4b58>
>>> print t
<Swig Object of type 'TestClass *' at 0x7f6584ae4b58>
>>> print t.__unicode__()
unicode: TestClass: 0
TestClass: 0
>>> print t.__unicode__
<built-in method __unicode__ of TestClass object at 0x7f6584ae4b58>

预期的输出是隐含地在“print t”调用__str__() 我错过了什么?

要让str(x)为使用swig -python -builtin生成的SWIG包装对象调用自己的C ++代码,您需要使用适当的槽来注册您的函数。 这是在SWIG中使用%feature("python:slot", ...)的,例如:

%module test

%include <std_string.i>

%feature("python:slot", "tp_str", functype="reprfunc") foo::as_string;

%inline %{
struct foo {
  std::string as_string() const { return "Hello world"; }
};
%}

借助SWIG 2.0和Python 2.7,我可以运行:

import test

print str(test.foo())
print repr(test.foo())

结果如下:

Hello world
<Swig Object of type 'foo *' at 0xb727ac40>

插槽允许快速调度标准对象函数调用 - 这是-builtin获得的大部分内容。

您可以查看可用插槽及其类型的完整列表以及相应的SWIG 2.0文档

基于Flexo的答案,这为我提供了我想要的功能(源文件和cmake不变)。

TestClass.i

%module TestClass

%{
#include <sstream>
#include "TestClass.h"
%}
%include "TestClass.h"

//http://stackoverflow.com/questions/2548779/how-to-stringfy-a-swig-matrix-object-in-python
%define __STR__(class_name) 
%feature("python:slot", "tp_str", functype="reprfunc") class_name::py_to_string();

%extend class_name{
    const char* py_to_string() { 
      std::ostringstream out; 
      out << *$self; 
      return out.str().c_str(); 
    }
}
%enddef

__STR__(TestClass); 

测试:

matthias@rp3deb:~/dvl/swig_str_minimal$ python -c "import TestClass; print TestClass.TestClass()"
TestClass: 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM