c++ - 在 cython 中伪造模板

标签 c++ templates cython

这个问题与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 声明为 publicreadonly,这将使它对 Python 可见,但这不适用于更复杂的类型(正如您在评论中提到的那样)。

您要做的是实现一个“虚拟”属性。这在 C++ 中甚至行不通:当您尝试访问不存在的属性时,您会遇到编译器错误,即使存在具有该属性的派生类也是如此。

通常,您可以通过将属性访问转换为调用cdef 方法来解决此问题,which is “virtual” ,但具体如何操作取决于您要解决的实际问题。

关于c++ - 在 cython 中伪造模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32210716/

相关文章:

python - 在 cython 中向量化具有两个数组作为输入的类的函数

c++ - 清除终端屏幕

c++ - 无法使用罗技 C920 访问 cv::VideoCapture 的属性

python - Cython 随机滚动不会产生预期的输出

c++ - 为什么我不能专门化功能模板?

c++ - 显式特化已删除的主模板

python - 多线程prange循环抛出 "double free or corruption (fasttop)"错误

c++ - C++ 中的名称重整

c++ - 一种后递增运算符,它允许一个人按指定的步长递增

javascript - 模板中的 Kendo 数据绑定(bind)