2011-06-30 18 views
6

Hice un pequeño fragmento de código porque todavía estoy tratando de descubrir los detalles del uso de super(). ¿Por qué este trozo se ejecuta en este TypeError?¿Estoy usando super() correctamente?

a = SecondClass() 
TypeError: __init__() takes exactly 2 arguments (1 given) 

Entonces, la función SecondClass.meth() se supone que debe imprimir la cadena, pero me falta claramente algo conceptualmente.

class FirstClass (object): 
    def __init__ (self, value): 
     self.value = value 
     print self.value 

class SecondClass (FirstClass): 
    def meth (self): 
     super (FirstClass,self).__init__(value = "I am a strange string") 

a = SecondClass() 
a.meth() 
+3

Llamar al constructor de la superclase desde un método de subclase es una idea ... * interesante *. –

Respuesta

8

Esto no es nada que ver con super. No define explícitamente un __init__ para SecondClass, pero, como hereda de FirstClass, hereda FirstClass 's __init__. Por lo tanto, no puede crear una instancia del objeto sin pasar el parámetro value.

Editar Aceptar. El primer punto, como han mencionado otros, es que siempre debe utilizar la clase actual en su super llamada, no la superclase - en este caso super(SecondClass, self). Eso es porque super significa "obtener el padre de la clase x", así que obviamente quiere decir "obtener el padre de SecondClass", que es FirstClass.

El segundo punto es que no tiene sentido llamar al método __init__ dentro de meth. __init__ es ya se llama al crear una instancia del objeto. O bien su subclase define su propia versión, que puede elegir si llama o no su propio súper método; o, como en este caso, no es así, en cuyo caso se llama automáticamente a la versión de la superclase.

Permítame repetir eso, porque sospecho que esta es la pieza que falta en su comprensión: el objetivo de las subclases es que todo lo que no anule específicamente, se hereda de todos modos. super es solo para aquellos casos en los que desea anular algo, pero aún así utilizar la lógica de la superclase así como.

Así que aquí es un ejemplo tonto:

class FirstClass(object): 
    def __init__ (self, value="I am the value from FirstClass"): 
     print value 

    def meth(self): 
     print "I am meth from FirstClass" 

    def meth2(self): 
     print "I am meth2 from FirstClass" 

class SecondClass(FirstClass): 
    def __init__ (self): 
     print "I am in SecondClass" 
     super(SecondClass, self).__init__(value="I am the value from SecondClass") 

    def meth(self): 
     print "I am meth from SecondClass" 


a=FirstClass() # prints "I am the value from FirstClass" 
b=SecondClass() # prints *both* "I am in SecondClass" *and* "I am the value from SecondClass 

a.meth() # prints "I am meth from FirstClass" 
b.meth() # prints "I am meth from SecondClass" 

a.meth2() # prints "I am meth2 from FirstClass" 
b.meth2() # *also* prints "I am meth2 from FirstClass", because you didn't redefine it. 
+0

Gracias ...¿Podría proporcionar un ejemplo simple de usar super de una segunda clase? – Louis93

+1

Agregó una carga más de explicación y algo de código. –

+0

Gotcha. Gran ejemplo y gran explicación. Finalmente hizo clic. – Louis93

3

El código de segunda clase debe ser así:

class SecondClass (FirstClass): 
    def meth (self): 
     super (SecondClass,self).__init__(value = "I am a strange string") 
1

función Fix metanfetamina

class SecondClass (FirstClass): 
    def meth (self): 
     super (SecondClass,self).__init__(value = "I am a strange string") 
2

El primer argumento de super() debe ser la corriente clase, no a la clase padres:

class SecondClass(FirstClass): 
    def meth(self): 
     super(SecondClass, self).__init__(value="I am a strange string") 

Python encontrará la función real que será ca lleno por sí mismo. En este caso, es la clase principal, pero este puede no ser el caso cuando se trata de herencia múltiple.

Cuestiones relacionadas