这个问题与this one有关,因为它应该是一个解决方案,但不起作用,我想知道为什么。我们的想法是让模板的不同实例化成为某个abstract-y类的派生类,其函数只需调用派生类的方法即可。宾语。但是,它完全无法工作:
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)
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'
但它完全是......
答案 0 :(得分:2)
当Cython编译print(self.v)
时,它必须决定是否发出代码以访问Python级或C级属性。由于没有为Vector类声明名为v
的cdef属性,因此它会发出Python级访问的代码。
在派生类中,v
类中的iVector
属性为“... stored directly in the object’s C struct.” 。它不能从Python获得,只能从C中获得,导致您看到的错误。
您可以将v
声明为public
或readonly
,这将使其对Python可见,但这不适用于更复杂的类型(正如您在评论中提到的那样)。
您要做的是实现“虚拟”属性。这在C ++中甚至不起作用:在尝试访问不存在的属性时会出现编译器错误,即使存在具有它的派生类也是如此。
通常,您可以通过将属性访问转换为调用cdef
方法which is “virtual”来解决此问题,但具体如何操作取决于您尝试解决的实际问题。