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):

我在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):
        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标签有太多的流量,所以没有什么能很快获得太多的选票。除非事情经常被否决,否则我会非常担心。我认为这个问题的问题在于,“签名与以前的声明不一致”是合理的,清楚地表明了什么是错误的,简单的解决办法是不这样做。您可能应该通过更改签名来明确解决了什么问题,因为这才是真正的问题所在(同时仍然试图保持简单,这很难…)