English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Funzioni incorporate di Python
La funzione built-in super() viene utilizzata per chiamare un metodo di una classe superiore (superclasse).
super() è utilizzato per risolvere problemi di ereditarietà multipla, la chiamata diretta dei metodi della superclasse tramite il nome della classe funziona bene in caso di ereditarietà singola, ma in caso di ereditarietà multipla, può sorgere una serie di problemi come l'ordine di ricerca (MRO), la chiamata duplicata (ereditarietà a diamante) e altri.
MRO è l'elenco dell'ordine di risoluzione dei metodi delle classi, che è anche l'elenco dell'ordine in cui si risolvono i metodi dei superclassi.
In Python, super() ha due principali casi d'uso:
ci permette di evitare l'uso esplicito del nome della superclasse
Gestione dell'ereditarietà multipla
In caso di ereditarietà singola, ci permette di utilizzare la superclasse tramite super().
class Mammal(object): def __init__(self, mammalName): print(mammalName, 'è un animale a sangue caldo.') class Dog(Mammal): def __init__(self): print('Il cane ha quattro zampe.') super().__init__('cane') d1 = Dog()
Risultato dell'output
Il cane ha quattro zampe. Il cane è un animale a sangue caldo.
In questo caso, abbiamo chiamato il metodo __init__() della classe Mammal (da Dog) tramite il codice
super().__init__('Dog')
invece di
Mammal.__init__(self, 'Dog')
Poiché non è necessario specificare il nome della superclasse al momento della chiamata dei membri, è facile modificare il nome della superclasse (se necessario).
# Modificare la superclasse in CanidaeFamily class Dog(CanidaeFamily): def __init__(self): print('Il cane ha quattro zampe.') # Non modificare questo super().__init__('cane')super() ha integrato un oggetto proxy che sostituisce l'oggetto, il quale può chiamare i metodi della superclasse tramite delega. Questo si chiama indirettiva (la capacità di utilizzare super() per riferirsi all'oggetto di base)
Poiché l'indirettiva è calcolata in tempo di esecuzione, possiamo utilizzare diversi superclassi in momenti diversi (se necessario).
class Animal: def __init__(self, Animal): print(Animal, 'è un animale'); class Mammal(Animal): def __init__(self, mammalName): print(mammalName, 'è un animale a sangue caldo.') super().__init__(mammalName) class NonWingedMammal(Mammal): def __init__(self, NonWingedMammal): print(NonWingedMammal, "non vola.") super().__init__(NonWingedMammal) class NonMarineMammal(Mammal): def __init__(self, NonMarineMammal): print(NonMarineMammal, "non può nuotare.") super().__init__(NonMarineMammal) class Dog(NonMarineMammal, NonWingedMammal): def __init__(self): print('Il cane ha 4 zampe.'); super().__init__('cane') d = Dog() print('') bat = NonMarineMammal('pipistrello')
Risultato dell'output
Il cane ha 4 zampe. Il cane non può nuotare. Il cane non può volare. Il cane è un animale a sangue caldo. Il cane è un animale Il pipistrello non può nuotare. Il pipistrello è un animale a sangue caldo. Il pipistrello è un animale
L'ordine di risoluzione dei metodi (MRO) è l'ordine di ereditarietà dei metodi da utilizzare in presenza di più ereditarietà. Puoi visualizzare il MRO utilizzando l'attributo __mro__.
>>> Dog.__mro__ (<class 'Dog'>, <class 'NonMarineMammal'>, <class 'NonWingedMammal'>, <class 'Mammal'>, <class 'Animal'>, <class 'object'>)
Ecco come funziona il MRO:
I metodi chiamati in un'override deriva sono sempre chiamati prima dei metodi della classe base.
Nel nostro esempio, la classe Dog viene chiamata prima di NonMarineMammal o NoneWingedMammal. Questi due sono chiamati prima di Mammal, che a sua volta viene chiamato prima di Animal, e l'oggetto (object) viene chiamato prima di Animal.
Se ci sono più superclassi, ad esempio Dog (NonMarineMammal, NonWingedMammal) che hanno più superclassi, viene prima chiamato il metodo NonMarineMammal, perché è il primo ad apparire.