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 superse 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 supera suppere 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 superpalavra - 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