[Tut] What is __init__ in Python? - Printable Version +- Sick Gaming (https://www.sickgaming.net) +-- Forum: Programming (https://www.sickgaming.net/forum-76.html) +--- Forum: Python (https://www.sickgaming.net/forum-83.html) +--- Thread: [Tut] What is __init__ in Python? (/thread-96425.html) |
[Tut] What is __init__ in Python? - xSicKxBot - 07-27-2020 What is __init__ in Python? <div><p>When reading over other people’s Python code, many beginners are puzzled by the <code>__init__(self)</code> method. What’s its purpose? This article answers this question once and for all.</p> <figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"> <div class="wp-block-embed__wrapper"> <div class="ast-oembed-container"><iframe title="What is __init__ in Python?" width="1400" height="788" src="https://www.youtube.com/embed/HgquEfCW1SQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div> </div> </figure> <p><strong>What’s the purpose of <code>__init__(self)</code> in Python? </strong></p> <p class="has-pale-cyan-blue-background-color has-background">The reserved Python method <code>__init__()</code> is called the <em>constructor </em>of a class. You can call the constructor method to create an object (=instance) from a class and initialize its attributes.</p> <figure class="wp-block-image size-large"><img src="https://blog.finxter.com/wp-content/uploads/2020/07/pythonint-1024x576.jpg" alt="Python __init__ method constructor" class="wp-image-11424" srcset="https://blog.finxter.com/wp-content/uploads/2020/07/pythonint-scaled.jpg 1024w, https://blog.finxter.com/wp-content/uploads/2020/07/pythonint-300x169.jpg 300w, https://blog.finxter.com/wp-content/uploads/2020/07/pythonint-768x432.jpg 768w, https://blog.finxter.com/wp-content/uploads/2020/07/pythonint-150x84.jpg 150w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure> <p>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__</code> 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.</p> <p><strong>Interactive Example</strong>: Before I’ll explain it to you, let’s open your knowledge gap. Consider the following example:</p> <p> <iframe src="https://trinket.io/embed/python/fbc1b43146" marginwidth="0" marginheight="0" allowfullscreen="" width="100%" height="356" frameborder="0"></iframe> </p> <p><em><strong>Exercise</strong>: Add one argument color to the <code>__init__</code> method and make the code run without error!</em></p> <p>Let’s dive into this simple example in great detail.</p> <h2>How to Use the __init__ Method in Practice? A Simple Example</h2> <p>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 <a href="https://blog.finxter.com/python-cheat-sheets/">download the PDF here</a>). 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.</p> <div class="wp-block-image"> <figure class="aligncenter is-resized"><a href="https://blog.finxter.com/object-oriented-programming-terminology-cheat-sheet/" target="_blank" rel="noreferrer noopener"><img src="https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1-791x1024.jpg" alt="" class="wp-image-2163" width="198" height="256" srcset="https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1.jpg 791w, https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1-232x300.jpg 232w, https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1-768x994.jpg 768w, https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1-100x129.jpg 100w, https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1-864x1118.jpg 864w, https://blog.finxter.com/wp-content/uploads/2019/03/CheatSheet-Python-8_-OO-Terminology-1-1200x1553.jpg 1200w" sizes="(max-width: 198px) 100vw, 198px" /></a></figure> </div> <p>You’ve learned that the <code>__init__</code> method is the constructor method of a class. You call the constructor method to create new instances (or <em>objects</em>). But how exactly does this play out in practice? Before we dive into the correct use, we need to understand the <em>arguments </em>(or <em>parameters</em>) of the constructor method.</p> <h3>The Self Argument</h3> <p>The <code>__init__</code> constructor requires at least one argument. According to the <a href="https://www.python.org/dev/peps/pep-0570/">PEP8 standard</a>, it’s good practice to denote this argument as <code>self</code>. In any case, the <code>self</code> 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"</code> to set the newly-created dog’s <code>color</code> attribute to the string <code>"blue"</code>. </p> <p>Let’s have a look at the following basic code example:</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Dog: def __init__(self): self.color = "blue" bello = Dog() print(bello.color) # blue</pre> <ol> <li>We create a new class Dog with the constructor <code>__init__(self)</code>. </li> <li>We create a new instance of the class <code>Dog</code> named <code>bello</code>. 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()</code>. Again, Python implicitly passes a reference to the newly created instance (<code>bello</code>) to the constructor <code>__init__</code>. </li> <li>We print the color attribute of the newly-created <code>bello</code> instance. The result is the string value <code>"blue"</code> as defined in the constructor.</li> </ol> <p>However, this minimal example is unrealistic. Some dogs are brown, others are black, and only some are blue.</p> <h3>Multiple Constructor Arguments</h3> <p>So how can we create different dogs with different colors? We can easily achieve this by using more arguments, in addition to <code>self</code>, when defining our constructor <code>__init__</code>. Here’s another example where we create two dogs with different colors. Can you spot their colors?</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Dog: def __init__(self, color): self.color = color bello = Dog("blue") print(bello.color) # blue alice = Dog("brown") print(alice.color) # brown</pre> <p>In contrast to the first example, we now define the constructor <code>__init__(self, color)</code> with two arguments rather than one. </p> <p>The first is the <code>self</code> argument as before. The second is a custom argument <code>color</code> that is passed through by the caller of the constructor. In our case, we create two Dog instances, <code>bello</code> and <code>alice</code>, by specifying the <code>color</code> argument for both. </p> <p>Note that the <code>self</code> argument is handled implicitly by the Python programming environment: Python simply passes a reference to the respective <code>Dog</code> instance to the <code>__init__</code> constructor.</p> <h2>What’s the Difference between the Constructor and the Initializer?</h2> <p>Well, I haven’t used a very accurate terminology in the previous paragraphs. I used the term “constructor” for both the call <code>Dog()</code> and the call <code>__init__()</code>. But only the former call can be denoted as <em>constructor method</em> because only this call actually creates a new instance. At the time, we call the method <code>__init__</code>, the instance has already been created (Python passes it to us via the <code>self</code> argument). That’s why a more precise term for the <code>__init__</code> method is <strong><em>initializer method</em></strong>. That’s how I’ll denote it in the following to make up for it. <img src="https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f609.png" alt="?" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p> <h2>What’s the Meaning of the Underscores in the __init__ Method Name?</h2> <p>I’ve written a whole article about the <a href="https://blog.finxter.com/underscore-in-python/">meaning of the underscore in Python</a>. Check it out if this topic interests you further. The key takeaway, however, is the following:</p> <p>The double underscore “__” (called <em>“dunder“</em>) 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”).</p> <h2>How to Use __init__ in an Inherited Class?</h2> <p>An inherited class is a class that inherits all attributes and methods from a parent class. Here’s an example:</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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</pre> <p>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.</p> <p>Now, we also create a new class <code>CuteDog</code> that inherits all attributes from the parent class <code>Dog</code>. You can define inheritance by specifying the name of the parent class within the brackets after the child class: <code>CuteDog(Dog)</code>.</p> <p>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.</p> <p>The more Pythonic way, however, is to use the <code>super()</code> function that makes it easier for you to access the parent class:</p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">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</pre> <p>With the help of the <code>super()</code> function, you can easily reuse the initializer method of the parent class. </p> <p>Let’s have a look at a few related questions.</p> <h2>Is __ init __ Necessary in Python?</h2> <p><strong>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:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Dog: None bello = Dog() bello.color = "blue" print(bello.color) # blue</pre> <p>How beautiful! You can even create empty classes and “fill in” the methods and attributes later in Python.</p> <h2>What Does __ init __ Return? </h2> <p><strong>The <code>__init__</code> method itself returns nothing. Technically, Python first uses the constructor method <code>Dog()</code> before it uses <code>__init__</code> to initialize all attributes. Hence, only the constructor returns the newly-created instance.</strong></p> <h2>Can __init__ Return a Value?</h2> <p><strong>No. The only return value that doesn’t cause a runtime error is <code>None</code>. All other return values cause an error. See the following code example:</strong></p> <pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class Dog: def __init__(self, color): self.color = color return 0 bello = Dog("blue") # TypeError: __init__() should return None, not 'int'</pre> <p>So never use any return value in the __init__ method and you’re good to go.</p> <h2>Where to Go from Here?</h2> <p>Thanks for reading through the whole article. You’ve learned that the <code>__init__</code> name is reserved for the Python initializer method that is called within the constructor. </p> <p>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. </p> <p>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…</p> <p><a href="https://blog.finxter.com/subscribe/">Join tens of thousands of Python coders (100% free)!</a></p> </div> https://www.sickgaming.net/blog/2020/07/25/what-is-__init__-in-python/ |