为什么在Python中调用运算符重载而不是覆盖?

时间:2017-07-28 15:32:17

标签: python python-3.x oop operator-overloading override

如果我想改变继承方法的行为,我会这样做:

class a:
    def changeme():
        print('called a')

class b(a):
    def changeme():
        print('called b')

我相信这是Python中覆盖的一个例子。

但是,如果我想重载一个运算符,我会做一些非常相似的事情:

class c:
    aNumber = 0
    def __add__(self, operand):
        print("words")
        return self.aNumber + operand.aNumber

a = c()
b = c()
a.aNumber += 1
b.aNumber += 2
print(a + b) # prints "words\n3"

我认为可能在python中实际上覆盖了运算符方法,因为我们重载using optional parameters并且我们只是将它称为运算符重载超出约定。

但它也不能成为覆盖,因为'__add__' in object.__dict__.keys()False;方法需要是父类的成员才能被覆盖(并且所有类在创建时都从object继承)。

我理解的差距在哪里?

2 个答案:

答案 0 :(得分:2)

重载意味着2个方法具有相同的名称和不同的签名+返回类型。覆盖意味着具有SAME名称的2个方法,其中子方法具有不同的功能。重载和覆盖之间的主要区别在于,在重载时,我们可以对于类上的不同任务多次使用具有不同参数的相同功能名称。和重写意味着我们可以在派生类中使用相同名称函数名称和基类的相同参数。这也被称为程序中代码的可重用性。

答案 1 :(得分:2)

我想由于最初的问题专门询问了我自己理解中的差距,我最适合回答它。去图。

我无法理解的是,重写取决于继承,而重载则不然。相反,Python matches methods for overloading based on name only

对于重写方法的子类,该方法确实需要存在于父类中。因此,def __add__部分不是覆盖的示例。

(在这种情况下,我也没有完全理解,如果解释器看到+运算符,它将查看操作数的类以获得__add__ {{3}的定义}。)

因为+运算符实际上是__add__()的别名,所以使用相同的名称。运算符重载实际上是一个重载的例子,因为我们正在改变名称(+__add__)在使用新参数调用时的行为(在我的示例中,类{{1}的对象})。