tags:

views:

106

answers:

2

In Python, consider I have the following code:

>>> class SuperClass(object):
    def __init__(self, x):
        self.x = x


>>> class SubClass(SuperClass):
    def __init__(self, y):
        self.y = y
        # how do I initialize the SuperClass __init__ here?

How do I initialize the SuperClass __init__ in the subclass? I am following the Python tutorial and it doesn't cover that. When I searched on Google, I found more than one way of doing. What is the standard way of handling this?

A: 

Both

SuperClass.__init__(self, x)

or

super(SubClass,self).__init__( x )

will work (I prefer the 2nd one, as it adheres more to the DRY principle).

See here: http://docs.python.org/reference/datamodel.html#basic-customization

adamk
@adamk: DRY stands for?
Jeremy
wrong. super only works with new-style classes, and is the only proper way to call a base when using new-style classes. Furthermore, you also need to pass 'self' explicitly using the old-style construct.
Ivo van der Wijk
I think you meant `SuperClass.__init__(self, x)`
Cristian Ciupitu
@Jeremy - Don't repeat yourserlf... ; @Cristian - thanks, edited.
adamk
@Ivo - the OP gave a new-style class in the example, and there's little point in talking about the difference between new-style and old-style as no one should use old-style any more. The link I gave (to the Python docs) suggest that there's more than one "proper" way to call the super-class `__init__`.
adamk
+2  A: 

Python (until version 3) supports "old-style" and new-style classes. New-style classes are derived from 'object' and are what you are using, and invoke their base class through super(), e.g.

class X(object):
  def __init__(self, x):
    pass

  def doit(self, bar):
    pass

class Y(X):
  def __init__(self):
    super(Y, self).__init__(123)

  def doit(self, foo):
    return super(Y, self).doit(foo)

Because python knows about old- and new-style classes, there are different ways to invoke a base method, which is why you've found multiple ways of doing so.

For completeness sake, old-style classes call base methods explicitly using the base class, i.e.

def doit(self, foo):
  return X.foo(self, foo)

But since you shouldn't be using old-style anymore, I wouldn't care about this too much.

Python 3 only knows about new-style classes (no matter if you derive from object or not).

Ivo van der Wijk
I see. But I read using `super` was not recommended in an article, though I could not understand it. Should I worry about it at this stage, I just started with Python.
Jeremy
I think I know which article you mean ("super considered harmful"). However, there are no alternatives, this is how it works. Python's multiple-inheritance makes the whole super() mechanism somewhat obscure. Just try to keep your model simple to avoid such confusion.
Ivo van der Wijk
@Ivo: Thanks and yes I meant that one. It came up while I was searching. ty for the help.
Jeremy
@Ivo: If you do read this, http://codepad.org/LvOdWcXj .. is this the right way to do it?
Jeremy
Look good to me!
Ivo van der Wijk
@Ivo: Thanks :)
Jeremy