Новое поведение магии super()
было добавлено, чтобы избежать нарушения D.R.Y. (Не повторяйте себя), см. 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 был выпущен Guido, который initially envisioned super
becoming a keyword, и идея использования ячейки для поиска текущего класса was also his. Конечно, идея сделать это ключевым словом была частью first draft of the PEP.
Однако, это был сам Гвидо, который затем stepped away from the keyword idea as 'too magical', предлагая вместо этого текущую реализацию. Он anticipated that using a different name for super()
could be a problem:
Мой патч использует промежуточное решение: он предполагает, что вам нужно __class__
всякий раз, когда вы используете переменную с именем 'super'
. Таким образом, если вы (глобально) переименовать super
в supper
и использовать supper
но не super
, он не будет работать без аргументов (но он все равно будет работать, если вы передадите его либо __class__
или фактический класс объекта); если у вас есть несвязанная переменная с именем super
, все будет работать, но метод будет использовать медленный путь вызова , используемый для переменных ячейки.
Таким образом, в конце концов, это был сам Гвидо, что провозгласил, что с помощью ключевого слова super
не чувствовал себя хорошо, и что предоставление волшебной __class__
клетки является приемлемым компромиссом.
Я согласен с тем, что магическое, неявное поведение реализации несколько удивительно, но super()
является одной из самых неправильно применяемых функций на этом языке. Просто взгляните на все неправильные super(type(self), self)
или super(self.__class__, self)
приглашения, найденные в Интернете; если какой-либо из этого кода когда-либо вызывался из производного класса you'd end up with an infinite recursion exception. По меньшей мере упрощенный вызов 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
Я дам Armin сделать объяснения по этому [один] (http://lucumr.pocoo.org/2010/1/7/плюсы-и-против-о-питон-3 /). Это еще один хороший [post] (http://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/) –
, связанный: http://stackoverflow.com/q/36993577/674039 – wim