2009-01-28 12 views
101

En Python 2.5.2, el siguiente código plantea una TypeError:Python super() plantea TypeError

>>> class X: 
... def a(self): 
...  print "a" 
... 
>>> class Y(X): 
... def a(self): 
...  super(Y,self).a() 
...  print "b" 
... 
>>> c = Y() 
>>> c.a() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in a 
TypeError: super() argument 1 must be type, not classobj 

Si se sustituye la class X con class X(object), va a trabajar. ¿Cuál es la explicación para esto?

+2

su "Sin embargo, reemplazo la clase X con la clase X (objeto)" solucionado mi problema! thanx – AliBZ

Respuesta

124

La razón es que super() solo opera en las clases de nuevo estilo, lo que en la serie 2.x significa que se extiende desde el objeto.

+3

¿De qué versión de python se convirtió esto en comportamiento predeterminado? – Geo

+6

2.2 fue cuando se introdujeron las clases de estilo nuevo, 3.0 es donde se convirtieron en las predeterminadas. –

+6

@tsunami si quieres llegar a la superclase, haz "X.a (auto)" –

13

Además, no use super() a menos que sea necesario. No es la "cosa correcta" de propósito general que hacer con las clases de nuevo estilo que pueda sospechar.

hay momentos en que se está esperando la herencia múltiple y es posible que pueda desear, pero hasta que conozca los detalles peludas del MRO, mejor dejarlo como está y se adhieren a:

X.a(self) 
+2

¿es correcto porque en mis 6 meses de Python/Django he estado usando super como "lo correcto en general"? – philgo20

+1

Bueno, no * duele * por la herencia individual en sí mismo (excepto que es un poco más lento), pero tampoco te da nada por sí mismo. Debes diseñar cualquier método que necesite multiplicar-heredar (sobre todo '__init__') para pasar los argumentos de una manera limpia y sensata, de lo contrario obtendrás TypeErrors o problemas de depuración peores cuando alguien intente multiplicar-heredar usando tu clase . A menos que realmente haya diseñado para admitir MI de esta manera (lo cual es bastante complicado), probablemente sea mejor evitar la implicación de que "super" tiene que el método es seguro para MI. – bobince

1

Probé la varios métodos Xa(); sin embargo, parecen requerir una instancia de X para realizar un(), así que hice X(). a (uno mismo), que parece más completo que las respuestas anteriores, al menos para las aplicaciones que he encontrado. No parece ser una buena forma de manejar el problema, ya que hay construcción y destrucción innecesarias, pero funciona bien.

Mi aplicación específica era el módulo cmd.Cmd de Python, que evidentemente no es un objeto NewStyle por algún motivo.

Resultado final:

X().a(self) 
3

En caso de que ninguna de las respuestas mencionado claramente. Tu clase principal debe heredar de "objeto", lo que esencialmente lo convertiría en una nueva clase de estilo.

# python 3.x: 
class ClassName(object): # This is a new style class 
    pass 

class ClassName: # This is also a new style class (implicit inheritance from object) 
    pass 

# Python 2.x: 
class ClassName(object): # This is a new style class 
    pass 

class ClassName:   # This is a old style class 
    pass 
Cuestiones relacionadas