Cython - 试图修改已经在超类中声明的子类中的函数,但发生错误



我在jupyter-notebook中编写了这四个类。 前两个类在 Python 中,另外两个具有类似操作的类在 cython 中:

%load_ext cython
%%cython
# py_child inherits from py_parent
class py_parent:
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
def func1(self):
return self.var1 + self.var2
def func2(self):
return self.var1 * self.var2
class py_child(py_parent):
def func1(self, inp):
return self.var1 + self.var2, self.var1 + inp, self.var2 + inp
# In the next cell I coded these modules
# cy_child inherits from cy_parent
cdef class cy_parent:
cdef public:
int var1, var2
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
cpdef int func1(self):
return self.var1 + self.var2
cpdef int func2(self):
return self.var1 * self.var2
cdef class cy_child(cy_parent):
def __init__(self, var1, var2):
super().__init__(var1, var2)
cpdef tuple func1(self, int inp):
return self.var1 + self.var2, self.var1 + inp, self.var2 + inp

我为python类运行下面的代码,它工作得很好:

a = py_child(1,1)
print(a.func1(2)) 

但是对于cy_child和cy_parent,我收到此错误:

cpdef tuple func1(self, int inp):
^
------------------------------------------------------------

Signature not compatible with previous declaration

之后我也收到此错误:Call with wrong number of arguments (expected 1, got 2)

为什么此错误发生在cython类而不是python类上。
假设我希望超类cy_parent保持func1函数不变,并希望以我显示的方式修改其子类cy_child.func1函数。那我该如何修复错误呢? 任何建议将不胜感激。

如果您将cpdef更改为def,这将"工作",但您正在做的事情毫无意义。

继承通常表示"是">关系 - 即cy_child是一个cy_parent,应该能够做cy_parent能做的一切(可能还有其他一些事情)。因此,它可以在代码中任何可以使用cy_parent的地方使用。通过尝试更改函数签名,您可以做它,以便它可以做更长的事情做同样的事情,从而打破该规则。

使用cpdef函数,您要求Cython生成代码,以便以下代码生成对正确函数的快速C函数调用,无论它是传递cy_parent还是cy_child

def example(cy_parent x):
x.func1()

由于函数采用不同数量的参数,因此不可能做到这一点,因此 Cython (正确地)抱怨。使用纯 Python 代码,您将问题推迟到运行代码,但问题仍然存在(您将获得有关参数数量错误的异常)。

有两个"解决方案":

  1. 不应使用继承,因为它不表示您尝试编码的模型。
  2. 如果您只是想在cy_child上添加额外的功能,那么您应该为新函数指定一个不同的名称(因为它正在执行不同的事情)。这表示您仍然希望能够将cy_parentfunc1cy_child一起使用的情况,但您还希望选择使用额外的参数执行类似的操作。

最新更新