Notification texts go here Contact Us Buy Now!

Should super always be at the top of an __init__ method, or can it be at the bottom?

This totally depends on the use case. Consider this.

class Foo():
    def __init__(self):
        print(self.name)

    @property
    def name(self):
        return self.__class__.__name__


class Bar(Foo):
    def __init__(self, name):
        self.name = name
        super().__init__()

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

If you'd invoke super() before setting self.name within Bar.__init__ you'd get an AttributeError because the required name has not yet been set.

Is it bad form to have it at the bottom of an init method?

You're asking the wrong question. Regardless of whether it's bad from or not, there are valid use cases for moving the superclass initialization to the bottom of a sub-class's constructor. Where to put the call to the superclass's constructor entirely depends on the implementation of the superclass's constructor.

For example, suppose you have a superclass. When constructing the superclass, you want to give an attribute a certain value depending on an attribute of the subclasses:

class Superclass:
    def __init__(self):
        if self.subclass_attr:
            self.attr = 1
        else:
            self.attr = 2

As you can see from above, we expect the subclasses to have the attribute subclass_attr. So what does this mean? We can't initialize Supperclass until we've given the subclasses the subclass_attr attribute.

Thus, we have to defer calling the superclass's constructor until we initialize subclass_attr. In other words, the call to super will have to be put at the bottom of a subclasses constructor:

class Subclass(Superclass):
    def __init__(self):
        self.subclass_attr = True
        super(Superclass, self).__init__()

In the end, the choice of where to put super should not be based upon some style, but on what's necessary.

It depends on what happens in the parent class initialization.

Early initialization of parent is required

In the following example the Parent class needs to be initialized for the foo() method to work, thus super().__init__(foo_param) must be called early if it is needed in the initialization of Child.

class Parent:
    def __init__(self, foo_param: str):
        self._foo_param = foo_param

    def foo(self) -> FooResult:
        return do_something_with(self._foo_param)
        

class Child(Parent):
    def __init__(self, foo_param: str):
        super().__init__(foo_param)  # Early init
        result = self.foo()  # Initial foo call
        # Use result for something
Later initialization of parent is required

In the following example the Parent class requires that the Child class implements the abstract foo() method for it to be able to initialize, but the Child class needs to initialize a bit before it's implementation of the foo() method is ready. Thus super().__init__() can't come first.

class Parent(ABC):
    def __init__(self):
        result = self.foo()  # Initial foo call
        # Use result for something

    @abstractmethod
    def foo(self) -> FooResult:
        raise NotImplementedError()
        

class Child(Parent):
    def __init__(self, foo_param: str):
        self._foo_param = foo_param  # Some prep is required for 
`foo()` to work
        super().__init__()  # Late init call

    def foo(self) -> FooResult:
        return do_something_with(self._foo_param)

Post a Comment

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.