O novo super()
comportamento mágico foi adicionado para evitar violar o princípio DRY (Não se repita), veja PEP 3135 . Ter que nomear explicitamente a classe referenciando-a como global também é propenso aos mesmos problemas de religação que você descobriu consigo super()
:
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
O mesmo se aplica ao uso de decoradores de classe em que o decorador retorna um novo objeto, que religa o nome da classe:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
A super()
__class__
célula mágica evita esses problemas perfeitamente, fornecendo acesso ao objeto de classe original.
O PEP foi iniciado por Guido, que inicialmente imaginou super
se tornar uma palavra-chave , e a idéia de usar uma célula para pesquisar a classe atual também era dele . Certamente, a ideia de transformá-la em palavra-chave fazia parte do primeiro rascunho do PEP .
No entanto, foi de fato o próprio Guido quem se afastou da ideia de palavra-chave como 'muito mágica' , propondo a implementação atual. Ele antecipou que usar um nome diferente para super()
poderia ser um problema :
Meu patch usa uma solução intermediária: assume que você precisa __class__
sempre que você usa uma variável chamada 'super'
. Assim, se você (globalmente) renomear super
a supper
e uso supper
, mas não super
, ele não vai funcionar sem argumentos (mas será ainda trabalho, se você passá-lo tanto
__class__
ou o objeto de classe real); se você tiver uma variável não relacionada denominada super
, tudo funcionará, mas o método usará o caminho de chamada um pouco mais lento usado para variáveis de célula.
Então, no final, foi o próprio Guido que proclamou que o uso de uma super
palavra - chave não parecia certo e que fornecer uma __class__
célula mágica era um compromisso aceitável.
Concordo que o comportamento implícito e mágico da implementação é um tanto surpreendente, mas super()
é uma das funções mais mal aplicadas na linguagem. Basta dar uma olhada em todas as invenções super(type(self), self)
ou aplicações incorretas super(self.__class__, self)
encontradas na Internet; se algum desses códigos fosse chamado de uma classe derivada, você acabaria com uma exceção de recursão infinita . No mínimo, a super()
chamada simplificada , sem argumentos, evita esse problema.
Quanto ao renomeado super_
; referência apenas __class__
em seu método bem e ele vai trabalhar novamente. A célula é criada se você fizer referência aos nomes super
ou __class__
no seu método:
>>> 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