type not must multiple def comando classobj argument python python-3.x super

not - python super multiple inheritance



¿Por qué es la magia súper(Python) 3.x? (1)

En Python 3.x, se puede llamar a super() sin argumentos:

class A(object): def x(self): print("Hey now") class B(A): def x(self): super().x()

>>> B().x() Hey now

Para que esto funcione, se realiza algo de magia en tiempo de compilación, una consecuencia de lo cual es que el siguiente código (que se vuelve a super_ super a super_ ) falla:

super_ = super class A(object): def x(self): print("No flipping") class B(A): def x(self): super_().x()

>>> B().x() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in x RuntimeError: super(): __class__ cell not found

¿Por qué super() no puede resolver la superclase en tiempo de ejecución sin ayuda del compilador? ¿Hay situaciones prácticas en las que este comportamiento, o la razón subyacente para ello, podría morder a un programador incauto?

... y, como una pregunta complementaria: ¿hay algún otro ejemplo en Python de funciones, métodos, etc. que se pueda romper volviéndolos a unir a un nombre diferente?


Se agregó el nuevo comportamiento mágico super() para evitar violar el principio DRY (No repetir), ver PEP 3135 . Tener que nombrar explícitamente la clase al hacer referencia a ella como global también es proclive a los mismos problemas de reenlace que descubrió con super() sí mismo:

class Foo(Bar): def baz(self): return super(Foo, self).baz() + 42 Spam = Foo Foo = something_else() Spam().baz() # liable to blow up

Lo mismo se aplica al uso de decoradores de clase donde el decorador devuelve un nuevo objeto, que vuelve a enlazar el nombre de la clase:

@class_decorator_returning_new_class class Foo(Bar): def baz(self): # Now `Foo` is a *different class* return super(Foo, self).baz() + 42

La celda mágica super() __class__ elude estos problemas al darle acceso al objeto de la clase original.

El PEP fue iniciado por Guido, quien inicialmente se imaginó que se convertiría en una palabra clave , y la idea de usar una celda para buscar la clase actual también era suya . Ciertamente, la idea de convertirla en una palabra clave fue parte del primer borrador del PEP .

Sin embargo, fue el propio Guido quien se alejó de la idea de la palabra clave como "demasiado mágico" , proponiendo la implementación actual en su lugar. Anticipó que usar un nombre diferente para super() podría ser un problema :

Mi parche usa una solución intermedia: supone que necesita __class__ cada vez que usa una variable llamada ''super'' . Por lo tanto, si (globalmente) renombra super a la supper y utiliza la supper pero no es super , no funcionará sin argumentos (pero seguirá funcionando si lo pasa __class__ o el objeto de la clase real); si tiene una variable no relacionada denominada super , las cosas funcionarán, pero el método utilizará la ruta de llamada ligeramente más lenta utilizada para las variables de celda.

Entonces, al final, fue el propio Guido quien proclamó que usar una palabra clave super no se sentía bien, y que proporcionar una celda mágica __class__ era un compromiso aceptable.

Estoy de acuerdo en que el comportamiento mágico e implícito de la implementación es algo sorprendente, pero super() es una de las funciones más mal aplicadas en el lenguaje. Solo eche un vistazo a todas las invocaciones super(type(self), self) o super(self.__class__, self) encuentran en Internet; si se llamaba alguna vez de ese código desde una clase derivada , terminarías con una excepción de recursión infinita . Por lo menos, la llamada a super() simplificada, sin argumentos, evita ese problema.

En cuanto al super_ rebautizado; simplemente __class__ referencia a __class__ en su método también y funcionará nuevamente. La celda se crea si hace referencia a los nombres super o __class__ en su 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