Am I using super() correctly?
I made a small chunk of code because I'm still trying to figure out the specifics of using sup开发者_StackOverflow中文版er()
. Why does this chunk run to this TypeError
?
a = SecondClass()
TypeError: __init__() takes exactly 2 arguments (1 given)
Then, the SecondClass.meth()
function is supposed to print the string, but I'm clearly missing something conceptually.
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()
This isn't anything to do with super
. You don't define an __init__
for SecondClass
explicitly - but, because it inherits from FirstClass
, it inherits FirstClass
's __init__
. So you can't instantiate the object without passing in the value
parameter.
Edit OK. The first point, as others have mentioned, is that you must always use the current class in your super call, not the superclass - in this case super(SecondClass, self)
. That's because super means "get the parent of class x", so obviously you mean "get the parent of SecondClass" - which is FirstClass.
The second point is that it doesn't make sense to call the __init__
method inside meth
. __init__
is already called when you instantiate the object. Either your subclass defines its own version, which can choose whether or not to call its own super method; or, as in this case, it doesn't, in which case the superclass's version is called automatically.
Let me repeat that, because I suspect that this is the missing piece in your understanding: the whole point of subclassing is that anything you don't specifically override, gets inherited anyway. super
is only for those cases when you want to override something, but still use the logic from the super class as well.
So here's a silly example:
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.
The code for SecondClass should be like this:
class SecondClass (FirstClass):
def meth (self):
super (SecondClass,self).__init__(value = "I am a strange string")
The first argument of super() should be the current class, not the parent class:
class SecondClass(FirstClass):
def meth(self):
super(SecondClass, self).__init__(value="I am a strange string")
Python will find the actual function that will be called by itself. In this case it's the parent class' but this may not be the case when multiple inheritance is involved.
It should be
super(SecondClass, self)
See the python documentation on super()
Fix meth function
class SecondClass (FirstClass):
def meth (self):
super (SecondClass,self).__init__(value = "I am a strange string")
精彩评论