La nouvelle magie super()
comportement a été ajouté pour éviter de violer les DRY (Don't Repeat Yourself), principe, voir PEP 3135. Ayant explicitement le nom de la classe par référence mondiale est aussi sujette à la même reliaison des questions que vous avez découvert avec super()
lui-même:
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
La même chose s'applique à l'aide de la classe décorateurs où le décorateur renvoie un nouvel objet, qui relie le nom de la classe:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
La magie super()
__class__
de cellules élude ces questions gentiment en vous donnant accès à la classe d'origine de l'objet.
Le PEP a été lancé par Guido, qui initialement envisagé super
devenir un mot-clé, et l'idée d'utiliser une cellule à regarder jusqu'à la classe actuelle était aussi son. Certes, l'idée d'en faire un mot-clé a été le cadre de la première ébauche de la PEP.
Cependant, il était, en fait, Guido lui-même qui ensuite s'écarta de l'idée de mot clé est trop "magique', en proposant la mise en œuvre actuelle à la place. Il a prévu que l'utilisation d'un nom différent pour super()
pourrait être un problème:
Mon patch utilise une solution intermédiaire: elle suppose que vous avez besoin d' __class__
chaque fois que vous utilisez une variable nommée 'super'
. Ainsi, si vous (dans le monde)
renommer super
de supper
et l'utilisation supper
mais pas super
, ça ne marchera pas
sans arguments (mais il faudra encore travailler si vous passer soit
__class__
ou de la classe réelle de l'objet); si vous avez une autre
variable nommée super
, les choses vont fonctionner, mais la méthode utilise la
légèrement plus lent appel de chemin d'accès utilisé pour les cellules variables.
Donc, à la fin, il a été Guido lui-même qui a proclamé que l'utilisation d'un super
mot-clé ne se sentait pas bien, et que la fourniture d'une magie __class__
cellule était un compromis acceptable.
Je suis d'accord que la magie, implicite comportement de la mise en œuvre est un peu surprenant, mais super()
est l'un des plus mal appliquée fonctions dans la langue. Il suffit de prendre un coup d'oeil à tous les mal appliqué super(type(self), self)
ou super(self.__class__, self)
invocations trouvé sur Internet; si ce code n'a jamais été appelé à partir d'une classe dérivée de vous finirais avec une récurrence infinie exception. À tout le moins l'simplifié super()
appel, sans arguments, évite que le problème.
Comme pour le renommé super_
; il suffit de référence __class__
dans votre méthode, en tant que bien , et il va fonctionner à nouveau. La cellule est créé si vous utilisez super()
ou utiliser __class__
dans votre méthode:
>>> 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