English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
A função interna super() é usada para chamar um método de uma classe pai (superclasse).
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
在Python中,super()有两个主要用例:
使我们避免显式使用基类名称
处理多重继承
在单继承的情况下,它允许我们通过引用基类super()。
class Mammal(object): def __init__(self, mammalName): print(mammalName, 'é um animal de sangue quente.') class Dog(Mammal): def __init__(self): print('O cão tem quatro patas.') super().__init__('cão') d1 = Dog()
Resultados de saída
狗有四条腿。 Cão é um animal de sangue quente.
在这里,我们使用代码调用了Mammal类的__init__()方法(来自Dog类)
super().__init__('Dog')
代替
Mammal.__init__(self, 'Dog')
由于在调用成员时不需要指定基类的名称,因此可以轻松更改基类名称(如果需要)。
# 将基类更改为CanidaeFamily class Dog(CanidaeFamily): def __init__(self): print('O cão tem quatro patas.') # 无需更改此 super().__init__('cão')super()内建返回一个代理对象,代替对象,可以通过委托调用基类的方法。这称为间接(使用super()引用基础对象的能力)
由于间接是在运行时计算的,因此我们可以在不同时间使用不同的基类(如果需要)。
class Animal: def __init__(self, Animal): print(Animal, 'é um animal'); class Mammal(Animal): def __init__(self, mammalName): print(mammalName, 'é um animal de sangue quente.') super().__init__(mammalName) class NonWingedMammal(Mammal): def __init__(self, NonWingedMammal): print(NonWingedMammal, "não voo.") super().__init__(NonWingedMammal) class NonMarineMammal(Mammal): def __init__(self, NonMarineMammal): print(NonMarineMammal, "não pode nadar.") super().__init__(NonMarineMammal) class Dog(NonMarineMammal, NonWingedMammal): def __init__(self): print('Cão tem4com pernas.'); super().__init__('cão') d = Dog() print('') bat = NonMarineMammal('morcego')
Resultados de saída
Cão tem4com pernas. Cão não pode nadar. Cão não pode voar. Cão é um animal de sangue quente. Cão é animal Morcego não pode nadar. Morcego é um animal de sangue quente. Morcego é animal
A ordem de resolução de métodos (MRO) é a ordem na qual os métodos devem ser herdados em caso de múltipla herança. Você pode usar a propriedade __mro__ para ver o MRO.
>>> Dog.__mro__ (<class 'Dog'>, <class 'NonMarineMammal'>, <class 'NonWingedMammal'>, <class 'Mammal'>, <class 'Animal'>, <class 'object'>)
Isso é como funciona o MRO:
Os métodos sempre são chamados antes dos métodos da classe base na chamada de herança.
Em nosso exemplo, chamamos a classe Dog antes de NonMarineMammal ou NoneWingedMammal. Essas duas classes são chamadas antes de Mammal, que é chamado antes de Animal, e a classe Animal é chamada antes do objeto (object).
Se houver vários pais, por exemplo, Dog (NonMarineMammal, NonWingedMammal) com vários pais, então é chamado primeiro o método NonMarineMammal, porque ele aparece primeiro.