Python Cython-试图修改子类中已在超类中声明的函数,但出现错误
我在jupyter笔记本中对这四个类进行了编码。前两个类在python中,另外两个具有类似操作的类在cython中:Python Cython-试图修改子类中已在超类中声明的函数,但出现错误,python,class,inheritance,cython,Python,Class,Inheritance,Cython,我在jupyter笔记本中对这四个类进行了编码。前两个类在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):
%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))
但是对于孩子和父母,我得到了这个错误:cpdef tuple func1(self, int inp):
^
------------------------------------------------------------
签名与以前的声明不兼容
在那之后,我还得到了这个错误:
使用错误数量的参数调用(应为1,得到2)
为什么cython类而不是python类会发生此错误。假设我希望超类
cy\u parent
保持func1
函数不变,并希望以我显示的方式修改其子类cy\u child.func1
函数。那么我怎样才能纠正这个错误呢?
任何建议都将不胜感激。如果您将cpdef
更改为def
,这将“起作用”,但您所做的一切毫无意义
继承通常表示“是一种”关系,即cy\u子项
是cy\u父项
,应该能够做cy\u父项
可以做的一切事情(可能还有其他事情)。因此,它可以在任何可以使用cy\u父项的代码中使用。通过尝试更改函数签名,您正在创建它,以便它可以做更长的时间来完成相同的事情,从而打破了该规则
使用cpdef
函数,要求Cython生成代码,以便以下代码生成对正确函数的快速C函数调用,无论该函数是否传递了cy\u父函数
或cy\u子函数
:
def example(cy_parent x):
x.func1()
由于函数采用不同数量的参数,因此不可能这样做,因此Cython(正确地)抱怨。对于纯Python代码,您可以将问题推迟到运行代码,但问题仍然存在(您将得到一个关于错误参数数量的异常)
有两种“解决方案”:
您不应该使用继承,因为它不代表您试图编写的模型李>
如果您只是想在cy_child
上添加额外的功能,那么您应该为新函数指定一个不同的名称(因为它做的是不同的事情)。这表示您仍然希望能够将cy_parent
的func1
与cy_child
一起使用,但您还希望选择使用额外参数执行类似操作
在C中,返回类型需要保持一致,因此如果func1
在中返回int
,那么子类也需要返回int
。我明白了。因此,没有办法像纯python那样重写函数,我必须修改超类func。我说得对吗?如果你给我一个不那么抽象的例子,我可能会给出其他的建议。但是不是,如果父类有一个返回一种类型的方法,则重写需要返回相同的类型。没错。我想要的只是子类函数的额外功能。我在这个问题中使用的抽象代码太简单,而真正的代码有点复杂,但我必须说,你告诉了我我需要什么。我的问题大多是实际案例,但没有人投票支持它们。我能做些什么来为我的问题或答案赢得更多的选票(我要求它为下一次增加更多的质量)?我不认为Cython标签有太多的流量,所以没有什么能很快获得太多的选票。除非事情经常被否决,否则我会非常担心。我认为这个问题的问题在于,“签名与以前的声明不一致”是合理的,清楚地表明了什么是错误的,简单的解决办法是不这样做。您可能应该通过更改签名来明确解决了什么问题,因为这才是真正的问题所在(同时仍然试图保持简单,这很难…)