不管这种方法是否真的提供了更快的执行时间,我将解释一下如何去做。基本上,创建一个指向vector
可以通过 C 函数与 Python 交互的 C++ 的指针。然后,您可以将 C++ 代码包装在 Python 类中,隐藏ctypes
.
我将我认为有用的魔法方法包含在 Python 类中。您可以选择删除它们或添加更多以满足您的需要。不过,析构函数很重要。
C++
// vector_python.cpp
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
extern "C" void foo(vector<int>* v, const char* FILE_NAME){
string line;
ifstream myfile(FILE_NAME);
while (getline(myfile, line)) v->push_back(1);
}
extern "C" {
vector<int>* new_vector(){
return new vector<int>;
}
void delete_vector(vector<int>* v){
cout << "destructor called in C++ for " << v << endl;
delete v;
}
int vector_size(vector<int>* v){
return v->size();
}
int vector_get(vector<int>* v, int i){
return v->at(i);
}
void vector_push_back(vector<int>* v, int i){
v->push_back(i);
}
}
将其编译为共享库。在 Mac OS X 上,这可能看起来像,
g++ -c -fPIC vector_python.cpp -o vector_python.o
g++ -shared -Wl,-install_name,vector_python_lib.so -o vector_python_lib.so vector_python.o
Python
from ctypes import *
class Vector(object):
lib = cdll.LoadLibrary('vector_python_lib.so') # class level loading lib
lib.new_vector.restype = c_void_p
lib.new_vector.argtypes = []
lib.delete_vector.restype = None
lib.delete_vector.argtypes = [c_void_p]
lib.vector_size.restype = c_int
lib.vector_size.argtypes = [c_void_p]
lib.vector_get.restype = c_int
lib.vector_get.argtypes = [c_void_p, c_int]
lib.vector_push_back.restype = None
lib.vector_push_back.argtypes = [c_void_p, c_int]
lib.foo.restype = None
lib.foo.argtypes = [c_void_p]
def __init__(self):
self.vector = Vector.lib.new_vector() # pointer to new vector
def __del__(self): # when reference count hits 0 in Python,
Vector.lib.delete_vector(self.vector) # call C++ vector destructor
def __len__(self):
return Vector.lib.vector_size(self.vector)
def __getitem__(self, i): # access elements in vector at index
if 0 <= i < len(self):
return Vector.lib.vector_get(self.vector, c_int(i))
raise IndexError('Vector index out of range')
def __repr__(self):
return '[{}]'.format(', '.join(str(self[i]) for i in range(len(self))))
def push(self, i): # push calls vector's push_back
Vector.lib.vector_push_back(self.vector, c_int(i))
def foo(self, filename): # foo in Python calls foo in C++
Vector.lib.foo(self.vector, c_char_p(filename))
然后,您可以在解释器中对其进行测试(file.txt
仅包含三行乱码)。
>>> from vector import Vector
>>> a = Vector()
>>> a.push(22)
>>> a.push(88)
>>> a
[22, 88]
>>> a[1]
88
>>> a[2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "vector.py", line 30, in __getitem__
raise IndexError('Vector index out of range')
IndexError: Vector index out of range
>>> a.foo('file.txt')
>>> a
[22, 88, 1, 1, 1]
>>> b = Vector()
>>> ^D
destructor called in C++ for 0x1003884d0
destructor called in C++ for 0x10039df10