Объекты функции Python: descriptors, а Python использует протокол дескриптора для связывает функции экземпляра. Этот процесс вызывает связанный метод .
Привязка - это то, что делает аргумент «magic» self
, когда вы вызываете метод, и что делает объект property
автоматически вызывать методы при попытке использовать свойство как атрибут для экземпляров.
super()
с двумя аргументами вызывает тот же протокол дескриптора, когда вы пытаетесь использовать его для поиска методов родительских классов; super(Foo, self).bar()
будет пересекать родительские классы Foo
, пока не будет найден атрибут bar
, и если это объект, который является дескриптором, он будет связан с self
. Вызов bar
затем вызывает метод bound, который, в свою очередь, вызывает функцию, проходящую в аргументе self
как bar(self)
.
Чтобы сделать это, super()
объект хранит как класс (первый аргумент) self
аргумент, чтобы связать с, и тип self
объекта как атрибуты:
>>> 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>
При поиске атрибутов, определяется атрибут __mro__
атрибута __self_class__
, начиная с позиции __thisclass__
, и результаты привязаны.
super()
только с один аргумент пропустит атрибуты __self_class__
и __self__
, и не может сделать Lookups еще:
>>> 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'
Объект делает поддерживает протокол дескрипторов, так что вы можете связать это так же, как вы можете связать метод:
>>> super(Spam).__get__(spam, Spam)
<super: <class 'Spam'>, <Spam object>>
>>> super(Spam).__get__(spam, Spam).bar()
'bar on Foo'
Это означает, что вы можете хранить такой объект по классу и использовать его, чтобы пройти к родительским методам:
>>> class Eggs(Spam):
... pass
...
>>> Eggs.parent = super(Eggs)
>>> eggs = Eggs()
>>> eggs.parent
<super: <class 'Eggs'>, <Eggs object>>
>>> eggs.parent.bar()
'bar on Spam'
См [метод класса различия в Python: связаны, несвязанные и статические] (HTTP://stackoverflow.com/q/114214), что означает, что что-то связано или несвязано. –