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

SWIG C++ to Python: generate a subclass of Python list

本文关键字:Python 列表 子类 生成 C++ to SWIG      更新时间:2023-10-16

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

下面是一个示例:

例子.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);
        }
};

示例.cpp

#include "example.h"

例子.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)

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

my_list.toy_insert()
print(my_list)

应该返回[0,1,2].

感谢您的帮助

正如我在评论中提到的,您可以覆盖 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