Додано нову магічну 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