2009-01-21 12 views
12

Al utilizar Python super() hacer método de encadenamiento, hay que especificar explícitamente su propia clase, por ejemplo:¿Por qué tengo que especificar mi propia clase cuando uso super(), y hay una forma de evitarlo?

class MyDecorator(Decorator): 
    def decorate(self): 
     super(MyDecorator, self).decorate() 

tengo que especificar el nombre de mi clase MyDecorator como argumento para super(). Esto no es SECO. Cuando renombre mi clase ahora tendré que cambiarle el nombre dos veces. ¿Por qué se implementa esto de esta manera? ¿Y hay una manera de evitar el tener que escribir el nombre de la clase dos veces (o más)?

Respuesta

6

El BDFL está de acuerdo. Ver Pep 367 - New Super para 2.6 y PEP 3135 - New Super para 3.0.

+0

Enlace a la versión actual del PEP: http://www.python.org/dev/peps/pep-3135/ – sth

+0

'super()' sin argumentos * no * funciona en Python 2.6.1 – jfs

+0

PEP 367 parece haber sido "reemplazado". No veo evidencia de que esto se haya agregado a 2.7. Creo que es una función solo 3.x. – Vultaire

11

Sus deseos se hacen realidad:

Simplemente use python 3.0. En él, solo usa super() y hace super(ThisClass, self).

Documentación here. Ejemplo de código de la documentación:

class C(B): 
    def method(self, arg): 
     super().method(arg)  
     # This does the same thing as: super(C, self).method(arg) 
0

también se puede evitar escribir un nombre de clase concreta en las versiones anteriores de Python usando

def __init__(self): 
    super(self.__class__, self) 
    ... 
+4

No, eso no funcionará porque __class__ te dará la subclase más específica para la instancia, no necesariamente la que está en el contexto de la clase que estamos escribiendo. – airportyh

+2

Siento que es injusto para el autor rechazar esta respuesta. Esta respuesta hace una idea errónea ingenua pero común. Merece una declaración aquí, junto con la explicación de Toby de por qué esto no funciona. Vale la pena en los métodos de informes que NO funcionan, también. – gotgenes

3

Esta respuesta es incorrecta, intente:

def _super(cls): 
    setattr(cls, '_super', lambda self: super(cls, self)) 
    return cls 

class A(object): 
    def f(self): 
     print 'A.f' 

@_super 
class B(A): 
    def f(self): 
     self._super().f() 

@_super 
class C(B): 
    def f(self): 
     self._super().f() 

C().f() # maximum recursion error 

En Python 2 hay una forma de usar el decorador:

def _super(cls): 
    setattr(cls, '_super', lambda self: super(cls, self)) 
    return cls 

class A(object): 
    def f(self): 
     print 'A.f' 

@_super 
class B(A): 
    def f(self): 
     self._super().f() 

B().f() # >>> A.f 
Cuestiones relacionadas