1

I am trying to understand when to initialize a superclass when using inheritance in python. Initially I thought that just by declaring a class inheriting from a super class, ex. class my_class(superclass):, would make available all the superclass's attributes and methods to the subclass. Which makes sense for somebody coming from Java. Then I read that Python forces us to initialize superclasses before we can implement them in our subclass, either by using the superclass.init() or super().init(). Then I came across this piece of code where I am not initializing the parent's class, however Python gave me access to the self.queue attribute from superclass without having initialized the parent class. I read the Python documentation and sometimes I think I know what they mean and some other I dont. Can anyone please explain to me when do we have to initialize superclasses in our subclasses?

class QueueError(IndexError):
pass

class Queue:
    def __init__(self):
       self.queue = []
    def put(self,elem):
       self.queue.insert(0,elem)
    def get(self):
        if len(self.queue) > 0:
            elem = self.queue[-1]
            del self.queue[-1]
            return elem
        else:
            raise QueueError

    class SuperQueue(Queue):
    def isempty(self):
        if not self.queue:
            return True
        else:
            return False

que = SuperQueue()
que.put(1)
que.put("dog")
que.put(False)
for i in range(4):
    if not que.isempty():
        print(que.get())
    else:
        print("Queue empty")

1 Answer 1

2

In general, if you override __init__ in your subclass, you should call the super __init__ method only. This is necessary if you extend the superclass. But if you want to overwrite the whole __init__, you can also omit the super call.

Example:

You have class A that has one attribute value1. And now you need a second attribute, so you subclass A with B and overwrite the __init__ where you call the super class (A), so A can set value1 and in B you can not set value2.
But now you need some other attributes in C, but need the same methods as in A. So you can entirely overwrite __init__ and omit the super call to A.

class A:
    def __init__(self, value1):
        print("Initialize A")
        self.value1 = value1


class B(A):
    def __init__(self, value1, value2):
        super().__init__(value1)
        print("Initialize B")
        self.value2 = value2


class C(A):
    def __init__(self, value3):
        print("Initialize C")
        self.value3 = value3


a = A("foo")
b = B("foo", "bar")
c = C("baz")

print(a.value1)
print(b.value1, b.value2)
print(c.value3)
print(c.value1)

Output

$ python main.py
Initialize A
Initialize A
Initialize B
Initialize C
foo
foo bar
baz
Traceback (most recent call last):
  File "main.py", line 27, in <module>
    print(c.value1)
AttributeError: 'C' object has no attribute 'value1'

You can see C wasn't initialized with value1, because C didn't call A's __init__.

Sign up to request clarification or add additional context in comments.

1 Comment

In other words, we can says that a subclass automatically inherits all of the superclass's traits. But if a subclass tries to access the superclass traits, it will generate an AttributeError exception, only if we override the superclass init. Now I see what super().__init__() is doing, it is basically giving a subclass access to the superclass' traits defined in the superclass init when this one has been overrided in the subclass. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.