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

Why is it called operator overloading and not overriding in Python?

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

1
2
3
4
5
6
7
class a:
    def changeme():
        print('called a')

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

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

但是,如果我想让一个操作符过载,我会做一些非常类似的事情:

1
2
3
4
5
6
7
8
9
10
11
12
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
3"

我认为在python中可能真的重写了操作符方法,因为我们使用可选参数进行重载,我们只是称它为超出约定的操作符重载。

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

我的理解差距在哪里?


我想,既然最初的问题专门问了我自己理解中的差距,我最好能回答它。去想一想。

我未能理解的是,虽然重写依赖于继承,但重载并不依赖于继承。相反,python只根据名称匹配重载方法。

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

(在这种情况下,我也不完全理解,如果解释器看到一个+操作符,它将在操作数类中查找__add__magic方法的定义。)

因为+操作符本质上是__add__()的别名,所以使用了相同的名称。实际上,运算符重载是重载的一个例子,因为当使用新参数(在我的示例中,是类c的对象)调用它时,我们正在更改名称(+__add__的行为。


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