Додано нову магічну super()
поведінку, щоб уникнути порушення принципу DRY (не повторюй себе), див. PEP 3135 . Необхідність чітко називати клас, посилаючись на нього як на глобальний, також схильна до тих самих проблем, що повторюються, що ви виявили із super()
собою:
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
Це ж стосується використання декораторів класів, де декоратор повертає новий об’єкт, який відновлює назву класу:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
Чарівна super()
__class__
клітина прекрасно переходить до цих питань, надаючи вам доступ до оригінального об’єкта класу.
PEP був розпочатий Гвідо, який спочатку передбачав super
стати ключовим словом , і ідея використання комірки для пошуку поточного класу також була його . Звичайно, ідея зробити його ключовим словом була частиною першого проекту ПЕП .
Однак насправді був саме Гуїдо відмовився від ідеї ключових слів як "занадто магічної" , запропонувавши замість цього поточну реалізацію. Він припускав, що використання іншої назви super()
може бути проблемою :
Мій патч використовує проміжне рішення: воно передбачає, що вам потрібно __class__
щоразу, коли ви використовуєте змінну з назвою 'super'
. Таким чином, якщо ви (глобально) перейменовуєтесь super
наsupper
і використання , supper
але не super
, це не буде працювати без аргументів (але це все одно буде працювати , якщо ви передасте його або
__class__
або фактичний об'єкт класу); якщо у вас названа непов'язана змінна super
, все буде працювати, але метод використовуватиме дещо повільніший шлях виклику, який використовується для змінних комірок.
Отже, врешті-решт, саме Гвідо проголосив, що використовуючи a super
ключове слово не правильно, а надання магічної __class__
комірки є прийнятним компромісом.
Я погоджуюся, що магія, неявна поведінка реалізації дещо дивує, але super()
є однією з найбільш неправильно застосованих функцій у мові. Просто подивіться на всі неправильно застосовані super(type(self), self)
або super(self.__class__, self)
виклики, знайдені в Інтернеті; якщо будь-який з цього коду коли-небудь викликався з похідного класу, ви закінчилися нескінченним винятком рекурсії . Принаймні, спрощений super()
дзвінок без аргументів уникає цієї проблеми.
Щодо перейменованих super_
; просто посилання __class__
на ваш метод також, і він буде працювати знову. Ця комірка створюється, якщо ви посилаєтесь на super
або на __class__
імена у своєму методі:
>>> super_ = super
>>> class A(object):
... def x(self):
... print("No flipping")
...
>>> class B(A):
... def x(self):
... __class__ # just referencing it is enough
... super_().x()
...
>>> B().x()
No flipping