Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Am I using super() correctly?

I made a small chunk of code because I'm still trying to figure out the specifics of using super(). 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()
like image 372
Louis93 Avatar asked Jun 30 '11 16:06

Louis93


1 Answers

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.
like image 104
Daniel Roseman Avatar answered Sep 28 '22 09:09

Daniel Roseman