Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python convention: should I normally call the super class' __init__?

I read the highest rated answer to this question, and it says we should call the super class' __init__ if we need to, and we don't have to. But my question is more about convention.

Should I normally, as a general rule, always call the superclass' __init__ in my class' __init__, regardless of whether or not I currently 'need' the functionality in that method?

like image 582
Aviv Cohn Avatar asked Mar 14 '15 03:03

Aviv Cohn


People also ask

Does super () init have to be first?

If the class you're super ing requires the object to be in a certain state then you put it in that state before super ... If your class requires the object to be in a certain state before it can continue its initialisation and that's provided by a parent class then you super that first.

Why does a class need to manually call a superclass's __ init __ method in Python?

The main reason for always calling base class _init__ is that base class may typically create member variable and initialize them to defaults. So if you don't call base class init, none of that code would be executed and you would end up with base class that has no member variables.

Is super init necessary?

In general it is necessary. And it's often necessary for it to be the first call in your init. It first calls the init function of the parent class ( dict ). It typically creates its underlying data structure.

What does super () __ init __ do?

Understanding Python super() with __init__() methods When this method is called it allows the class to initialize the attributes of the class. In an inherited subclass, a parent class can be referred with the use of the super() function.


3 Answers

Some classes need their __init__ method to be called in order to work. They use their __init__ method sets attributes that will be needed.

Example:

class one ():
    def __init__ (self):
        self.number = 20
    def show_number(self):
        return self.number

If you inherit from the above class, you will need to call its __init__ method in order to define the attribute number. If the __init__ method is not called you could get an error when you try to call the method show_number.

As for the syntax, if nothing happens in the __init__ method of the inherited class you don't need to call it. If you think not calling the __init__ method would confuse others, you can always explain your reasoning with comments. It does not do any harm to call it even if you don't need it.

like image 63
cweb Avatar answered Oct 22 '22 01:10

cweb


This answer has some downvotes because the downvoters disagree with me on the focus, and perhaps on what "convention" means. I think we mostly agree on the actual practice when it comes to writing code.


No. You should not normally, as a general rule, always call the superclass's __init__ in your class's __init__, regardless of whether or not you currently "need" the functionality in that method.

But please note that my emphasis is on that last phrase, starting with "regardless", and that is what my "no" answer is meant to address. You shouldn't be throwing something into your Python code "just because someone told you to" or "just because that seems to be what most people are doing".

You should include something if it is needed, and not include something if it is not.

It is very often the case, some would argue that it is normally the case, that you do want to call the superclass's __init__ method in your subclass's __init__ method. I do this myself most of the time.

But why?

Crucially, it is not because of some "convention". I do it because my subclass normally needs the same initialization as the superclass, plus a bit of extra customization. Note that the extra customization is the whole reason for overriding __init__ in the first place. If the initialization of your subclass is meant to be identical to that of the superclass, then you shouldn't be defining your own __init__ at all.


It's not a convention in Python to code something you don't need. Some people have their own conventions to include unnecessary things; perhaps in the name of "defensive programming" or because they are used to a different language in which more boilerplate is required.

Where Python's conventions come in is when you have a choice between multiple ways to express something useful. It's true that Python does not emphasize brevity above all else. But that doesn't mean it emphasizes verbosity either. So let me add this, in case it's not clear:

You should normally, as a general rule, always avoid unnecessary boilerplate code. (And not just in Python.)

[For those who think the phrase "normally always" is awkward or nonsensical: I completely agree, but I was trying to emphasize my point by repeating the asker's own choice of words.]

like image 28
John Y Avatar answered Oct 22 '22 00:10

John Y


Yes. As a general rule you should call the superclass's __init__ from a subclass's __init__ method. This is not a Python convention, it is what OO best practice suggests you should do (given the language you happen to be using, leaves this decision up to you):

The superclass doesn't know about the subclass, but the subclass is expected to know about the semantics of the superclass it inherits from. Ultimately it is up to the subclass to maintain a consistent behavior of a true sub-typing (which unfortunately, the Python language does little to help the programmer with). You, as the subclass implementer get to decide whether or not you need to call the superclass __init__, just like you get to decide whether you do/don't need/want to call the superclass's implementation of any method you override. However, initialization of an object tends to be a pretty important step in the life-cycle of many objects. Until the object has been initialized one can argue the object is not truly an instance of the given class. It is an implied and important post-condition in ~all sane OO languages that when you instantiate an object certain things have happened and we can depend on those things having happened, initialization (or "construction" in other languages) being the central thing - whether it involves complex parameter validation and computed value generation, or is just a null op. So if you don't call super's initializer you better know exactly what your in for.

Another argument for calling super's __init__ as a general rule is, if you didn't write the superclass, or your not tightly controlling the version, the implementation of __init__ may change in future (does adding something to __init__ call for a major version bump? I'm not sure but I bet a lot of folks wouldn't bump the major version number for that, even if technically they should). So if you do call super's __init__ your code is less likely to break with updates to the superclass implementation.


Update: Should have read the linked question before answering this question. Most of the answers over there echo the general sentiment here - perhaps not in the same terms or as strongly in favor of calling __init__() as a general rule as I am. But I'll leave this answer for others that fall here.

like image 1
spinkus Avatar answered Oct 22 '22 02:10

spinkus