L'ereditarietà multipla — la possibilità di una classe di ereditare contemporaneamente da più classi genitore — è nata in Python ispirandosi ad altri linguaggi di programmazione orientata agli oggetti (ad esempio, C++), dove aiuta a creare mixin riutilizzabili. Lo sviluppo del meccanismo di ricerca dei metodi (MRO) ha richiesto molto tempo per garantire prevedibilità in caso di conflitti tra metodi.
Una classe può ottenere metodi con lo stesso nome da diverse classi base. Come determinare quale metodo utilizzare durante la chiamata? Senza uno schema chiaro, questo porta a errori difficili da individuare.
Python implementa l'algoritmo MRO (C3 linearization), che determina un ordine rigoroso per la ricerca dei metodi nella risoluzione dei conflitti nell' gerarchia. Tutto diventa trasparente se si utilizza la funzione super() e il metodo __mro__ delle classi per analizzare la catena di ereditarietà.
Esempio di codice:
class A: def foo(self): print("A") class B(A): def foo(self): print("B") super().foo() class C(A): def foo(self): print("C") super().foo() class D(B, C): def foo(self): print("D") super().foo() D().foo() print(D.__mro__)
Caratteristiche principali:
__mro__;Cosa succede se i nomi dei metodi dei genitori coincidono?
Risposta: La chiamata al metodo avverrà nell'ordine stabilito dal MRO. Il primo metodo trovato con il nome richiesto nella catena sarà quello che verrà eseguito.
È possibile utilizzare super() senza passare esplicitamente self?
Risposta: In Python 3 — sì, la chiamata super().method() nel corpo del metodo di una classe è equivalente alla chiamata esplicita super(Class, self).method(), ma solo all'interno della classe.
È possibile cambiare l'ordine MRO di una classe esistente?
Risposta: L'ordine MRO è statico dopo la dichiarazione della classe, ma può essere esaminato (o si può costruire una nuova classe con un diverso ordine di ereditarietà).
Nel progetto sono stati creati due mixin con metodi simili, la classe erede utilizza entrambi i mixin, ma chiama i metodi direttamente tramite il nome della classe, interrompendo l'ordine degli eventi.
Vantaggi:
Svantaggi:
Si utilizza super() in ogni metodo dei mixin, garantendo che la chiamata avvenga nella catena, senza saltare il comportamento necessario.
Vantaggi:
Svantaggi: