1

So, here's the problem..

if you do this:

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

why would you explicitly call init in child class to access parent class attribute? (class y has class x attribute anyway.)

class y(x):
  def __init__(self):
    x.__init__(self)

Cheers.

Edit:

I read this article https://linuxmeerkat.wordpress.com/2015/04/28/why-you-should-use-super-in-python/, it says "In real life we tend to run the initializer for every parent class. This is simply because of how program designs tend to be. In our simple example a way to solve this is to explicitly call the initializer of A:" Could someone please explain?

Roy
  • 63
  • 8

3 Answers3

0

Because the child class inherits from the parent class, of course, that means everything: methods, attributes and the constructor. So instead of rewrite all the __init__ code, you just use what is already written in the parent class. Hope it makes sense to you.

lch
  • 2,028
  • 2
  • 25
  • 46
0

The fact is that in python there is a clear distinction between class and instance attributes:

  • Attributes declared in the class body, outside any method, are class attributes, they are the same for each object of that class and are the ones that are inherited by the subclasses. Be aware of the fact that doing instance_obj.class_att = something doesn't change the value of the class attribute, but simply creates an instance attribute and hides the shared class attribute for that object.

  • Instance attributes are the ones that are declared with syntax instance_obj.att = something, they are not shared between instances and are the most similar thing to non-static attributes that you have in other programming languages and they are usually created in the init method.self is just a convention to indicate the instance object automatically passed to methods.

Here's an example:

class MyClass:
    c = 1                    #class attribute, the subclasses will inherit this
    def __init__(self):
        self.i = 1           #instance attribute

MyClass.c     #access attribute c of class MyClass
MyClass.i     #error! MyClass has no attribute i
x = MyClass() #calling __init__ creates instance attribute i for obj x
x.i           #access instance attribute i of object x
x.c           #access class attribute c of class MyClass
x.c = 2       #hide MyClass.c and create instance attribute c for obj x
x.c           #access instance attribute c of obj x

So, to sum up, doing:

class y(x):
    def __init__(self):
        x.__init__(self)

is useful because if the base class would have been something like this

class x:
    def __init__(self):
        self.i=1

you would have not been able to access the attribute i from any instances of y simply because they would not have it.

andre
  • 163
  • 8
  • Thanks but if base class attr changed, like in your example `self.i=1`, calling x.__init__(self) in `class y` will get the attribute `i` for `class y` , wouldn't it? – Roy Apr 03 '17 at 04:39
  • @Roy i is an instance attribute, but sure, that's the reason why you do that! – andre Apr 03 '17 at 08:33
  • Soz, how's `i` an instance attribute, if it's defined in `class x` already?? – Roy Apr 03 '17 at 08:44
  • @Roy I've edited my answer adding another example, I hope it helps. I suggest you to find a good reference and study OOP in python in detail to have a better understanding of what's going on. – andre Apr 03 '17 at 10:33
  • If `__init__` doesn't do anything *except* call `x.__init__`, you don't need to define it at all; `y` will just inherit `x.__init__`. – chepner Nov 21 '19 at 16:17
0

Instead of calling to the init function explicitly, you should use the super() method instead.

In python 3.0+, you can jusy use:

class y(x):
    def __init__(self):
        super().__init__()

In python 2.7 or under, use:

class y(x):
    def __init__(self):
        super(self.__class__, self).__init__()

super() lets you avoid referring to the base class explicitly.

Yuval Pruss
  • 8,716
  • 15
  • 42
  • 67