SWIG C++ to Python:生成 Python 列表的子类

Posted

技术标签:

【中文标题】SWIG C++ to Python:生成 Python 列表的子类【英文标题】:SWIG C++ to Python: generate a subclass of Python list 【发布时间】:2017-03-18 22:39:43 【问题描述】:

我正在使用 SWIG (v3) 将 C++ 代码包装到 Python 3。在 C++ 中,我有一个类 MyClass,它继承自 std::vector。我想用 Python 包装它,这样生成的 Python 类 MyClass 是标准 Python list 类的子类。这可能吗?

这是一个例子:

example.h

#include <vector>
#include <iostream>

using namespace std;

// List class
class MyList : public vector<int> 

    public:
        // Init
        MyList() : vector<int>() 
            this->insert(this->begin(),2);
            this->insert(this->begin(),1);
        

        // Toy insert function
        void toy_insert() 
        
            this->insert(this->begin(),0);
        
;

example.cpp

#include "example.h"

example.i

%module example

%
     #include "example.h"
%

%include "std_vector.i"

using namespace std;

%template(MyVector) std::vector<int>; // Nothing known about base class 'vector< int >' if we remove std:: here

%typemap(out) MyList* 
  int size = (*$1).size();
  $result = PyList_New(size);

  for (int i=0; i<size; i++) 
    PyList_SetItem($result, i, PyInt_FromLong((*$1)[i]));
  
;

// List class
class MyList : public std::vector<int> // Nothing known about base class 'vector< int >' if we remove std:: here

  public:
    MyList();
    void toy_insert();
;

run_example.py

import example

my_list = example.MyList()
print(my_list)

打印命令返回&lt;example.MyList; proxy of [1, 2] &gt;,但这不是我想要的。理想情况下,这应该只返回[1,2],但我仍然可以调用:

my_list.toy_insert()
print(my_list)

应该返回[0,1,2]

感谢您的帮助

【问题讨论】:

如果您的示例如您所愿返回[1,2],它将是一个Python 列表并且没有.toy_insert() 方法。您可以覆盖__str__ 和/或__repr__ 并使其显示 [1,2] 而不是默认的&lt;example.MyList; proxy of [1,2]&gt;。那么它仍然是一个包装的对象,你仍然可以调用.toy_insert()。顺便说一句,不建议在标题中使用using 谢谢,我想这是不可能的。这对用户来说就像一个列表,但当然不会神奇地继承 Python list 类的方法 - 似乎没有简单的方法可以做到这一点 【参考方案1】:

正如我在评论中提到的,您可以覆盖 SWIG 类型的显示。这是一个粗略的例子:

%module x

%
#include "example.h"
%

%include <windows.i>
%include <std_vector.i>

%template(MyVector) std::vector<int>;

%include "example.h"

%extend MyList 

const char*__repr__()

    // I was lazy.
    return "fancy representation";



输出:

>>> import x
>>> t=x.MyList()
>>> t
fancy representation
>>> t[0]
1
>>> t[1]
2
>>> t.toy_insert()
>>> t[0]
0
>>> t[1]
1
>>> t[2]
2

【讨论】:

以上是关于SWIG C++ to Python:生成 Python 列表的子类的主要内容,如果未能解决你的问题,请参考以下文章

无法为 c++ python 扩展编译 swig 生成的包装器

Python 错误:在 SWIG 生成的 C++ 模板代码模块中未定义构造函数

swig c++ to python (with numpy): error: use of undeclared identifier 'import_array'

SWIG - python 中的 C++ 代码

如何使用 SWIG 将 C++ 数组转换为 Python 列表?

如何让 Swig 发出 C++ 超类