Gli oggetti funzione Python sono descriptors e Python utilizza il protocollo descrittore su associa le funzioni a un'istanza. Questo processo produce un metodo associato .
Il collegamento è ciò che fa apparire l'argomento "magico" self
quando si chiama un metodo e ciò che rende un oggetto property
chiamata automaticamente i metodi quando si tenta di utilizzare la proprietà come un attributo su istanze.
super()
con due argomenti richiama lo stesso protocollo descrittore quando si tenta di utilizzarlo per cercare metodi sulle classi padre; super(Foo, self).bar()
attraverserà le classi genitore Foo
finché non viene trovato un attributo bar
e se si tratta di un oggetto che è un descrittore, verrà associato a self
. Chiamando il numero bar
, quindi chiama il metodo associato, che a sua volta chiama la funzione che passa nell'argomento self
come bar(self)
.
A tale scopo, il super()
oggetto memorizza sia la classe (primo argomento) l'argomento self
di legarsi con, e il tipo di oggetto self
come attributi:
>>> class Foo(object):
... def bar(self):
... return 'bar on Foo'
...
>>> class Spam(Foo):
... def bar(self):
... return 'bar on Spam'
...
>>> spam = Spam()
>>> super(Spam, spam)
<super: <class 'Spam'>, <Spam object>>
>>> super(Spam, spam).__thisclass__
<class '__main__.Spam'>
>>> super(Spam, spam).__self_class__
<class '__main__.Spam'>
>>> super(Spam, spam).__self__
<__main__.Spam object at 0x107195c10>
Quando guardando gli attributi, l'attributo __mro__
dell'attributo __self_class__
viene ricercato, a partire da una posizione oltre la posizione di __thisclass__
e i risultati vengono associati.
super()
con solo un argomento mancheranno gli attributi __self_class__
e __self__
, e non possono fare ricerche ancora:
>>> super(Spam)
<super: <class 'Spam'>, NULL>
>>> super(Spam).__self_class__ is None
True
>>> super(Spam).__self__ is None
True
>>> super(Spam).bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'bar'
L'oggetto fa supporta il protocollo descrittore, in modo da poter legano proprio come è possibile associare un metodo:
>>> super(Spam).__get__(spam, Spam)
<super: <class 'Spam'>, <Spam object>>
>>> super(Spam).__get__(spam, Spam).bar()
'bar on Foo'
Questo significa che è possibile memorizzare un tale oggetto su una classe e utilizzarlo per attraversare a metodi genitore:
>>> class Eggs(Spam):
... pass
...
>>> Eggs.parent = super(Eggs)
>>> eggs = Eggs()
>>> eggs.parent
<super: <class 'Eggs'>, <Eggs object>>
>>> eggs.parent.bar()
'bar on Spam'
Sede [differenze metodo di classe in Python: legato, non legati e statici] (http://stackoverflow.com/q/114214) per ciò che significa che qualcosa deve essere legato o non associato. –