Il builtin super () restituisce un oggetto proxy (oggetto temporaneo della superclasse) che ci permette di accedere ai metodi della classe base.
In Python, super()
ha due principali casi d'uso:
- Ci consente di evitare di utilizzare esplicitamente il nome della classe di base
- Lavorare con l'ereditarietà multipla
Esempio 1: super () con Single Inheritance
Nel caso di ereditarietà singola, ci consente di fare riferimento alla classe base tramite super()
.
class Mammal(object): def __init__(self, mammalName): print(mammalName, 'is a warm-blooded animal.') class Dog(Mammal): def __init__(self): print('Dog has four legs.') super().__init__('Dog') d1 = Dog()
Produzione
Il cane ha quattro zampe. Il cane è un animale a sangue caldo.
Qui, abbiamo chiamato il __init__()
metodo della classe Mammal (dalla classe Dog) usando il codice
super () .__ init __ ('Cane')
invece di
Mammifero .__ init __ (sé, 'Cane')
Poiché non è necessario specificare il nome della classe di base quando ne chiamiamo i membri, possiamo facilmente modificare il nome della classe di base (se necessario).
# changing base class to CanidaeFamily class Dog(CanidaeFamily): def __init__(self): print('Dog has four legs.') # no need to change this super().__init__('Dog')
Il super()
builtin restituisce un oggetto proxy, un oggetto sostitutivo che può chiamare i metodi della classe base tramite delega. Questo si chiama indiretto (capacità di fare riferimento all'oggetto base con super()
)
Poiché l'indirizzamento viene calcolato in fase di esecuzione, possiamo utilizzare classi di base diverse in momenti diversi (se necessario).
Esempio 2: super () con ereditarietà multipla
class Animal: def __init__(self, Animal): print(Animal, 'is an animal.'); class Mammal(Animal): def __init__(self, mammalName): print(mammalName, 'is a warm-blooded animal.') super().__init__(mammalName) class NonWingedMammal(Mammal): def __init__(self, NonWingedMammal): print(NonWingedMammal, "can't fly.") super().__init__(NonWingedMammal) class NonMarineMammal(Mammal): def __init__(self, NonMarineMammal): print(NonMarineMammal, "can't swim.") super().__init__(NonMarineMammal) class Dog(NonMarineMammal, NonWingedMammal): def __init__(self): print('Dog has 4 legs.'); super().__init__('Dog') d = Dog() print('') bat = NonMarineMammal('Bat')
Produzione
Il cane ha 4 zampe. Il cane non sa nuotare. Il cane non può volare. Il cane è un animale a sangue caldo. Il cane è un animale. Il pipistrello non sa nuotare. Il pipistrello è un animale a sangue caldo. Il pipistrello è un animale.
Ordine di risoluzione del metodo (MRO)
Method Resolution Order (MRO) è l'ordine in cui i metodi devono essere ereditati in presenza di ereditarietà multipla. È possibile visualizzare l'MRO utilizzando l' __mro__
attributo.
>>> Cane .__ mro__ (,,,,,)
Ecco come funziona MRO:
- Un metodo nelle chiamate derivate viene sempre chiamato prima del metodo della classe base.
Nel nostro esempio, la classe Dog viene chiamata prima di NonMarineMammal o NoneWingedMammal. Queste due classi sono chiamate prima di Mammal, che è chiamata prima di Animal, e la classe Animal è chiamata prima dell'oggetto. - Se ci sono più genitori simili
Dog(NonMarineMammal, NonWingedMammal)
, i metodi di NonMarineMammal vengono richiamati per primi perché appare per primo.
Per saperne di più super()
, visita il super () considerato super di Python!