问题描述
我正在尝试使用 SWIG 打印我为 Python 包装的 C++ 类.我遵循了文档和这个问题:How to stringfy a swigpython中的矩阵对象
扩展的 __str__
函数在那里,但是当我从 Python 打印对象时它没有被调用.让我举一个最小的例子:
TestClass.h
#include 类测试类{私人的:int my_int;民众:测试类():my_int(0){}朋友 std::ostream&运算符<
TestClass.cpp
#include "TestClass.h"int main(){使用命名空间标准;测试类 t;cout<<<<结束;}
TestClass.i
%define __STR__() \const char* __str__() {std::cout <<*$self <
CMakeLists.txt
cmake_minimum_required (VERSION 2.6)项目(battery_lib_cpp)设置(CMAKE_VERBOSE_MAKEFILE 1)FIND_PACKAGE(需要 SWIG)包括(${SWIG_USE_FILE})设置(CMAKE_SWIG_FLAGS-墙")#寻找PythonlibsFIND_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$ pythonPython 2.7.8(默认,2014 年 7 月 26 日,15:25:14)[GCC 4.9.1] 在 linux2 上输入帮助"、版权"、信用"或许可"以获取更多信息.>>>导入测试类>>>t = TestClass.TestClass()>>>打印 t<位于 0x7f1dffcb2b90 的TestClass *"类型的 Swig 对象>>>>打印 t.__str__()测试类:0测试类:0>>>打印 t.__str__<0x7f1dffcb2b90处的TestClass对象的内置方法__str__>
__unicode__()
预期输出是在print t"处隐式调用 __str__()
.我错过了什么?
要让 str(x)
为使用 swig 生成的 SWIG 包装对象调用您自己的 C++ 代码 -python -builtin
你需要使用适当的槽来注册你的函数.这是通过 SWIG 中的 %feature("python:slot", ...)
完成的,例如:
%module 测试%include %feature("python:slot", "tp_str", functype="reprfunc") foo::as_string;%排队 %{结构 foo {std::string as_string() const { return "Hello world";}};%}
使用 SWIG 2.0 和 Python 2.7,我可以运行:
导入测试打印 str(test.foo())打印 repr(test.foo())
结果:
Hello world<0xb727ac40 处类型为foo *"的 Swig 对象>
插槽允许快速调度标准对象函数调用 - 这是 -builtin
为您带来的很大一部分.
您可以查看完整的可用插槽列表及其类型以及相应的 SWIG 2.0 文档.
I'm trying to print C++ classes that I wrapped for Python using SWIG. I have followed the documentation and this question: How to stringfy a swig matrix object in python
The extended __str__
function is there, but it isn't called when I print the object from Python. Let me give a minimal example:
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)
After building (cmake ., make), I then get the following:
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>
Another test for __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>
Expected output would be to have __str__()
called at "print t" implicitly. What am I missing?
To get str(x)
to call your own C++ code for a SWIG wrapped object that was produced with swig -python -builtin
you need to use the appropriate slot to register your function. That's done with %feature("python:slot", ...)
in SWIG, e.g.:
%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"; }
};
%}
With SWIG 2.0 and Python 2.7 lets me run:
import test
print str(test.foo())
print repr(test.foo())
Which results in:
Hello world
<Swig Object of type 'foo *' at 0xb727ac40>
Slots allow standard object function calls to be dispatched quickly - it's a big chunk of what -builtin
gains you.
You can see the complete list of available slots and their types and the corresponding SWIG 2.0 documentation of them.
这篇关于使用 SWIG 打印为 Python 包装的 C++ 类时未调用 __str__()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!