π𧡠Here's a thread on the dunder method `__init__`.
You can't say you **know** Python if you don't know this, so...
In this thread we will cover the dunder method `__init__` and its role in Python OOP.
Here we go π
βinitβ is short for βinitialiseβ or βinitialisationβ.
That, right there, tells you what `__init__` is for!
When you create a new instance of a class, you use the method `__init__` to initialise it:
In other words, you use `__init__` to customise the instance.
Here's an example for you.
Say you want to create a class that represents people.
People have names, right? And whenever you create a new person, you want to give them their name.
It will be the __init__'s job, then, to take that name and associate it with the person object.
After writing the `__init__` like in the code image above, we can create persons and give them names!
What's interesting here is that we don't call `__init__` explicitly.
When we create a new person with `Person()`, `__init__` will be called for us π
When we created a new person with my name, `__init__` was called in the background.
The argument that I gave to `Person`, which was a string with my name, was passed in to `__init__` directly.
Notice how `__init__` expects two arguments (self, and name)!
But I only passed one argument to `Person`, which was my name.
The βselfβ argument is also put there auto-magically by Python.
It is a reference to the object itself, and it allows us to *know* what's the object that we are manipulating.
Let's print that reference π
As you can see, inside `__init__` we printed `self`, and the output was exactly the same as the output from the object itself in the REPL.
Now, a very important thing here to notice is that βselfβ is NOT a special word.
I can use any other name I like for the first argument π
What do I want to show with this?
I want to show that the βmagicβ is that the first argument is put there implicitly.
But there is nothing magic about the word βselfβ itself.
It's just a VERY STRONG recommendation that you use βselfβ for the name of that argument.
Now, what if we have a class hierarchy?
How should we initialise an instance that belongs in a hierarchy?
Here is a simple hierarchy for you π
All workers are persons, so let's say that the `Worker` class is a `Person` subclass.
How do we write the `__init__` for `Worker`?
Let's say that a worker gets a name and also the company they work for.
The βnameβ is something that the worker got because a `Person` gets it, so we should let `Person` initialise that for us.
In other words, the `Worker.__init__` has to call `Person.__init__` π
If you look at the `Woker.__init__` method, you will see how this initialisation is usually done.
`super().__init__` is used to call the parent's `__init__`.
We also *start* with the parent's `__init__`, so that the `Worker` can already rely on the `Person`'s attributes.
These aren't strict rules.
But it's generally what you want to do:
π first call the parent `__init__` with `super()`;
π then initialise the child class by setting attributes, etc.
Bonus π:
`__init__` is also used as a file name (so, `__init__.py`) in directories that we want Python to treat as packages.
You will often find these `__init__.py` files empty, but they can also do some module initialisation, e.g. to set the dunder attribute `__all__`.
That's it for this thread π§΅.
This was a bird's eye view of what `__init__` does/what it's for! I hope it was useful.
I love teaching Python π.
Are you learning π Python π?
If you are, follow @mathsppblog for more π₯Β great educational content on Python!
TL;DR:
π `__init__` initialises a new instance;
π use `super()` in an object hierarchy to do the parent initialisation; and
π `__init__` can also be used as a file name to initialise packages.
I'll be covering other dunder methods later...
So, see you soon π ?
β’ β’ β’
Missing some Tweet in this thread? You can try to
force a refresh