Sto eseguendo Python 2.5, quindi questa domanda potrebbe non essere applicabile a Python 3. Quando si crea una gerarchia di classi diamond usando l'ereditarietà multipla e si crea un oggetto della classe derivata-più, Python fa la cosa giusta (TM). Chiama il costruttore per la classe derivata-most, quindi le sue classi genitore come elencate da sinistra a destra, quindi il nonno. Ho familiarità con Python MRO; non è una mia domanda Sono curioso di sapere come l'oggetto restituito da Super riesca effettivamente a comunicare alle chiamate di super nelle classi genitore l'ordine corretto. Si consideri questo codice di esempio:Come fa il "super" di Python a fare la cosa giusta?
#!/usr/bin/python
class A(object):
def __init__(self): print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__()
class C(A):
def __init__(self):
print "C init"
super(C, self).__init__()
class D(B, C):
def __init__(self):
print "D init"
super(D, self).__init__()
x = D()
Il codice fa la cosa intuitiva, stampa:
D init
B init
C init
A init
Tuttavia, se si commento la chiamata a super nella funzione init di B, né A né funzione init di C è chiamato. Ciò significa che la chiamata a super di B è in qualche modo consapevole dell'esistenza di C nella gerarchia di classi generale. So che super restituisce un oggetto proxy con un operatore get sovraccarico, ma in che modo l'oggetto restituito da super nella definizione di init di D comunica l'esistenza di C all'oggetto restituito da super nella definizione di init di B? L'informazione che le successive chiamate di super uso sono memorizzate sull'oggetto stesso? Se è così, perché non è super invece self.super?
Edit: Jekke ha giustamente sottolineato che non è self.super perché super è un attributo della classe, non un'istanza della classe. Concettualmente questo ha senso, ma in pratica il super non è nemmeno un attributo della classe! Puoi testare questo nell'interprete facendo due classi A e B, dove B eredita da A e chiama dir(B)
. Non ha attributi super
o __super__
.
Super non è self.super perché super è una proprietà della classe, non dell'istanza. (Non capisco il resto della domanda). –
Irrilevante, forse; ma mi è stato consigliato da molte persone di non usare più Python 2.5, dato che Python 3 introduce così tante nuove funzionalità/risolve così tanti bug. – adam
Modifica in "in che modo l'oggetto restituito da super nella definizione di init di D comunica l'esistenza di C all'oggetto restituito da super nella definizione di init di B"? Credo che sia quello che stai chiedendo - potrebbe avere più senso :) –