2015-05-12 3 views
15

При чтении о super() object в Python, я прочитал следующее заявление:Как я могу использовать супер() с одним аргументом в питоне

Если второй аргумент опущен, супер возвращённый объект несвязанные

Что это значит и как я могу использовать super() с одним аргументом в коде?

+0

См [метод класса различия в Python: связаны, несвязанные и статические] (HTTP://stackoverflow.com/q/114214), что означает, что что-то связано или несвязано. –

ответ

15

Объекты функции 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' 
Смежные вопросы