Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tut] What is __init__ in Python?
1
What is __init__ in Python?

When reading over other people’s Python code, many beginners are puzzled by the
Code:
__init__(self)
method. What’s its purpose? This article answers this question once and for all.



What’s the purpose of
Code:
__init__(self)
in Python?


The reserved Python method
Code:
__init__()
is called the constructor of a class. You can call the constructor method to create an object (=instance) from a class and initialize its attributes.

[Image: pythonint-1024x576.jpg]

While this answers the question, if you’ve got any ambition in becoming a professional Python coder, it’s not enough to know that the
Code:
__init__
method is the constructor of a class. You also need to know how to use the constructor in your own projects—and how to customize its arguments. A thorough understanding of the constructor serves as a strong foundation for more advanced concepts in object-oriented Python programming. Read on to learn the other half of the equation.

Interactive Example: Before I’ll explain it to you, let’s open your knowledge gap. Consider the following example:

https://trinket.io/embed/python/fbc1b43146

Exercise: Add one argument color to the
Code:
__init__
method and make the code run without error!


Let’s dive into this simple example in great detail.

How to Use the __init__ Method in Practice? A Simple Example

We’ll use some terms of object-oriented programming in Python to explain our example. Make sure to study the following cheat sheet (you can also download the PDF here). Click the image to get the cheat sheet (opens in a new tab). If you’re already comfortable with basic object-orientation terminologies like classes and instances, simply read on.

[Image: CheatSheet-Python-8_-OO-Terminology-1-791x1024.jpg]

You’ve learned that the
Code:
__init__
method is the constructor method of a class. You call the constructor method to create new instances (or objects). But how exactly does this play out in practice? Before we dive into the correct use, we need to understand the arguments (or parameters) of the constructor method.

The Self Argument

The
Code:
__init__
constructor requires at least one argument. According to the PEP8 standard, it’s good practice to denote this argument as
Code:
self
. In any case, the
Code:
self
argument points to the newly-created instance itself and it allows you to manipulate the instance attributes of the new instance. In the dog example, you’d use
Code:
self.color = "blue"
to set the newly-created dog’s
Code:
color
attribute to the string
Code:
"blue"
.

Let’s have a look at the following basic code example:

Code:
class Dog: def __init__(self): self.color = "blue" bello = Dog() print(bello.color) # blue
  1. We create a new class Dog with the constructor
    Code:
    __init__(self)
    .

  2. We create a new instance of the class
    Code:
    Dog
    named
    Code:
    bello
    . There are two interesting observations: First, we use the class name rather than the constructor name to create the new instance. Python internally calls the __init__ method for us. Second, we don’t pass any argument when calling
    Code:
    Dog()
    . Again, Python implicitly passes a reference to the newly created instance (
    Code:
    bello
    ) to the constructor
    Code:
    __init__
    .

  3. We print the color attribute of the newly-created
    Code:
    bello
    instance. The result is the string value
    Code:
    "blue"
    as defined in the constructor.

However, this minimal example is unrealistic. Some dogs are brown, others are black, and only some are blue.

Multiple Constructor Arguments

So how can we create different dogs with different colors? We can easily achieve this by using more arguments, in addition to
Code:
self
, when defining our constructor
Code:
__init__
. Here’s another example where we create two dogs with different colors. Can you spot their colors?

Code:
class Dog: def __init__(self, color): self.color = color bello = Dog("blue") print(bello.color) # blue alice = Dog("brown") print(alice.color) # brown

In contrast to the first example, we now define the constructor
Code:
__init__(self, color)
with two arguments rather than one.

The first is the
Code:
self
argument as before. The second is a custom argument
Code:
color
that is passed through by the caller of the constructor. In our case, we create two Dog instances,
Code:
bello
and
Code:
alice
, by specifying the
Code:
color
argument for both.

Note that the
Code:
self
argument is handled implicitly by the Python programming environment: Python simply passes a reference to the respective
Code:
Dog
instance to the
Code:
__init__
constructor.

What’s the Difference between the Constructor and the Initializer?

Well, I haven’t used a very accurate terminology in the previous paragraphs. I used the term “constructor” for both the call
Code:
Dog()
and the call
Code:
__init__()
. But only the former call can be denoted as constructor method because only this call actually creates a new instance. At the time, we call the method
Code:
__init__
, the instance has already been created (Python passes it to us via the
Code:
self
argument). That’s why a more precise term for the
Code:
__init__
method is initializer method. That’s how I’ll denote it in the following to make up for it. [Image: 1f609.png]

What’s the Meaning of the Underscores in the __init__ Method Name?

I’ve written a whole article about the meaning of the underscore in Python. Check it out if this topic interests you further. The key takeaway, however, is the following:

The double underscore “__” (called “dunder“) is used to make an instance attribute or method private (cannot be accessed from outside the class) — when used as leading dunder. When used as enclosing dunder (e.g. “__init__”) it indicates that it is a special method in Python (called “magic method”).

How to Use __init__ in an Inherited Class?

An inherited class is a class that inherits all attributes and methods from a parent class. Here’s an example:

Code:
class Dog: def __init__(self, color): self.color = color class CuteDog(Dog): def __init__(self, color): Dog.__init__(self, color) self.hairs = True bello = CuteDog('brown') print(bello.hairs) # True print(bello.color) # brown

Inheritance is very important in Python. In the example, the parent class is the class Dog you already know from above. The initializer method __init__ defines the color of this dog.

Now, we also create a new class
Code:
CuteDog
that inherits all attributes from the parent class
Code:
Dog
. You can define inheritance by specifying the name of the parent class within the brackets after the child class:
Code:
CuteDog(Dog)
.

The interesting thing is that the __init__ method of the child class CuteDog calls the __init__ method of the parent class. This makes sense because the child class has the same attributes as the parent class—and they need to be initialized, too.

The more Pythonic way, however, is to use the
Code:
super()
function that makes it easier for you to access the parent class:

Code:
class Dog: def __init__(self, color): self.color = color class CuteDog(Dog): def __init__(self, color): super().__init__(color) self.hairs = True bello = CuteDog('brown') print(bello.hairs) # True print(bello.color) # brown

With the help of the
Code:
super()
function, you can easily reuse the initializer method of the parent class.

Let’s have a look at a few related questions.

Is __ init __ Necessary in Python?

No. You can simply skip the initializer method. As a result, your class won’t have any instance attributes directly after its creation. However, you can add instance attributes dynamically at any future point in time. Here’s an example:

Code:
class Dog: None bello = Dog() bello.color = "blue" print(bello.color) # blue

How beautiful! You can even create empty classes and “fill in” the methods and attributes later in Python.

What Does __ init __ Return?

The
Code:
__init__
method itself returns nothing. Technically, Python first uses the constructor method
Code:
Dog()
before it uses
Code:
__init__
to initialize all attributes. Hence, only the constructor returns the newly-created instance.


Can __init__ Return a Value?

No. The only return value that doesn’t cause a runtime error is
Code:
None
. All other return values cause an error. See the following code example:


Code:
class Dog: def __init__(self, color): self.color = color return 0 bello = Dog("blue") # TypeError: __init__() should return None, not 'int'

So never use any return value in the __init__ method and you’re good to go.

Where to Go from Here?

Thanks for reading through the whole article. You’ve learned that the
Code:
__init__
name is reserved for the Python initializer method that is called within the constructor.

The article requires a thorough understanding of the Python basics. Investing time to learn and study those is vital for your success as a professional coder.

To help people grow their skills in an automated, personalized way, I’ve created a free Python email course “Coffee Break Python” that grows your skill level in a seemingless way. Day after day after day…

Join tens of thousands of Python coders (100% free)!
Reply

Users browsing this thread:
1 Guest(s)

Forum Jump: