这个问题与this one有关,从某种意义上说,它应该是解决方案但不起作用,我想知道为什么。这个想法是让模板的不同实例成为某个抽象类的派生类,然后它们的函数只调用派生类对象上的方法。但是,它完全无法工作:
foo.pyx
from libcpp.vector cimport vector
cdef class Vector:
def show(self):
print(self.v)
cdef class iVector(Vector):
cdef vector[int] v
def __init__(self, v):
for e in v:
self.v.push_back(e)
cdef class lVector(Vector):
cdef vector[long] v
def __init__(self, v):
for e in v:
self.v.push_back(e)
设置.py
from distutils.core import setup, Extension
from Cython.Build import cythonize
e = Extension("foo", sources=["foo.pyx"], language="c++")
setup(ext_modules = cythonize([e]))
在 ipython 中
In [1]: import foo
In [2]: v = foo.iVector(range(5))
In [3]: v.show()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-ea66b5f25fed> in <module>()
----> 1 v.show()
/home/kartikv/Programs/foo.pyx in foo.Vector.show (foo.cpp:768)()
2 cdef class Vector:
3 def show(self):
----> 4 print(self.v)
5
6 cdef class iVector(Vector):
AttributeError: 'foo.iVector' object has no attribute 'v'
但它确实...
最佳答案
当 Cython 编译 print(self.v)
时,它必须决定是否发出代码以访问 Python 级或 C 级属性。由于没有为 Vector 类声明名为 v
的 cdef 属性,因此它发出 Python 级访问的代码。
另一方面,在派生类中,iVector
类中的v
属性是“... stored directly in the object’s C struct.” 。 .它在 Python 中不可用,只能在 C 中使用,从而导致您看到的错误。
您可以将 v
声明为 public
或 readonly
,这将使它对 Python 可见,但这不适用于更复杂的类型(正如您在评论中提到的那样)。
您要做的是实现一个“虚拟”属性。这在 C++ 中甚至行不通:当您尝试访问不存在的属性时,您会遇到编译器错误,即使存在具有该属性的派生类也是如此。
通常,您可以通过将属性访问转换为调用cdef
方法来解决此问题,which is “virtual” ,但具体如何操作取决于您要解决的实际问题。
关于c++ - 在 cython 中伪造模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32210716/