<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mscneuro.neuro.uni-bremen.de/index.php?action=history&amp;feed=atom&amp;title=Class</id>
	<title>Class - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mscneuro.neuro.uni-bremen.de/index.php?action=history&amp;feed=atom&amp;title=Class"/>
	<link rel="alternate" type="text/html" href="https://mscneuro.neuro.uni-bremen.de/index.php?title=Class&amp;action=history"/>
	<updated>2026-07-06T12:21:35Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://mscneuro.neuro.uni-bremen.de/index.php?title=Class&amp;diff=329&amp;oldid=prev</id>
		<title>Davrot at 16:15, 17 October 2025</title>
		<link rel="alternate" type="text/html" href="https://mscneuro.neuro.uni-bremen.de/index.php?title=Class&amp;diff=329&amp;oldid=prev"/>
		<updated>2025-10-17T16:15:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 16:15, 17 October 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;== The goal ==&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Class has a very important job as a core container type in Python. It is really hard to find a good overview how to use them in a good practice manner.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Class has a very important job as a core container type in Python. It is really hard to find a good overview how to use them in a good practice manner.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l142&quot;&gt;Line 142:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 141:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== [https://docs.python.org/3/library/functions.html#property @property()] ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== [https://docs.python.org/3/library/functions.html#property @property()] ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{: .topic-optional} &lt;/del&gt;This is an optional topic!&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;&#039;&#039;&lt;/ins&gt;This is an optional topic!&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;&#039;&#039;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;If a variable starts with one _ this tells us that it is “private” and we shouldn’t touch it directly with our dirty hands from the outside. However, we can use @property to control the communication with the outside world:  &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;If a variable starts with one _ this tells us that it is “private” and we shouldn’t touch it directly with our dirty hands from the outside. However, we can use @property to control the communication with the outside world:  &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l419&quot;&gt;Line 419:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 420:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;print(ClassA.__mro__) # -&amp;gt; (&amp;lt;class &amp;#039;__main__.ClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassB&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;object&amp;#039;&amp;gt;)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;print(ClassA.__mro__) # -&amp;gt; (&amp;lt;class &amp;#039;__main__.ClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassB&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;object&amp;#039;&amp;gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;print(ClassB.__mro__) # -&amp;gt; (&amp;lt;class &#039;__main__.ClassB&#039;&amp;gt;, &amp;lt;class &#039;__main__.BaseClassB&#039;&amp;gt;, &amp;lt;class &#039;__main__.BaseClassA&#039;&amp;gt;, &amp;lt;class &#039;object&#039;&amp;gt;)&amp;lt;/syntaxhighlight&amp;gt;As you can see: Which version of the functions survives can be complicated. If you want to understand the MRO (Method resolution order) you can look up [[wikipedia:C3_linearization|C3 linearization]]. Personally, I would try to avoid this unclear situations everywhere.  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;print(ClassB.__mro__) # -&amp;gt; (&amp;lt;class &#039;__main__.ClassB&#039;&amp;gt;, &amp;lt;class &#039;__main__.BaseClassB&#039;&amp;gt;, &amp;lt;class &#039;__main__.BaseClassA&#039;&amp;gt;, &amp;lt;class &#039;object&#039;&amp;gt;)&amp;lt;/syntaxhighlight&amp;gt;As you can see: Which version of the functions survives can be complicated. If you want to understand the MRO (Method resolution order) you can look up [[wikipedia:C3_linearization|C3 linearization]]. Personally, I would try to avoid this unclear situations everywhere. &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;We can define more precisely and prevent surprises: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;We can define more precisely and prevent surprises: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Davrot</name></author>
	</entry>
	<entry>
		<id>https://mscneuro.neuro.uni-bremen.de/index.php?title=Class&amp;diff=156&amp;oldid=prev</id>
		<title>Davrot: Created page with &quot; == The goal == Class has a very important job as a core container type in Python. It is really hard to find a good overview how to use them in a good practice manner.  Questions to [mailto:davrot@uni-bremen.de David Rotermund]  == Basics == Class is the core component of object-oriented programming (OOP). A class is an [https://docs.python.org/3/reference/datamodel.html object] that can...&quot;</title>
		<link rel="alternate" type="text/html" href="https://mscneuro.neuro.uni-bremen.de/index.php?title=Class&amp;diff=156&amp;oldid=prev"/>
		<updated>2025-10-15T13:32:43Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot; == The goal == Class has a very important job as a core container type in Python. It is really hard to find a good overview how to use them in a good practice manner.  Questions to [mailto:davrot@uni-bremen.de David Rotermund]  == Basics == &lt;a href=&quot;https://en.wikipedia.org/wiki/Class_(computer_programming)&quot; class=&quot;extiw&quot; title=&quot;wikipedia:Class (computer programming)&quot;&gt;Class&lt;/a&gt; is the core component of &lt;a href=&quot;https://en.wikipedia.org/wiki/Object-oriented_programming&quot; class=&quot;extiw&quot; title=&quot;wikipedia:Object-oriented programming&quot;&gt;object-oriented programming&lt;/a&gt; (OOP). A class is an [https://docs.python.org/3/reference/datamodel.html object] that can...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
== The goal ==&lt;br /&gt;
Class has a very important job as a core container type in Python. It is really hard to find a good overview how to use them in a good practice manner.&lt;br /&gt;
&lt;br /&gt;
Questions to [mailto:davrot@uni-bremen.de David Rotermund]&lt;br /&gt;
&lt;br /&gt;
== Basics ==&lt;br /&gt;
[[wikipedia:Class_(computer_programming)|Class]] is the core component of [[wikipedia:Object-oriented_programming|object-oriented programming]] (OOP). A class is an [https://docs.python.org/3/reference/datamodel.html object] that can contain data i.e. class variables (also called fields, attributes or properties) and code, called class methods. Here we will look at the basic [https://docs.python.org/3/tutorial/classes.html#classes Python class]. For data science there is a simplified derivation available called dataclass.&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class MostSimplestClass:&lt;br /&gt;
    pass&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Instance ==&lt;br /&gt;
What is an instance? After defining a class we need to put it into memory. Every instance of a class generated in memory is… well… an instance. Here is an example how we create two instances of a class: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass(object):&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
instance_a = SimpleClass()&lt;br /&gt;
instance_a.variable_a = 1&lt;br /&gt;
&lt;br /&gt;
instance_b = SimpleClass()&lt;br /&gt;
instance_b.variable_a = 2&lt;br /&gt;
&lt;br /&gt;
print(instance_a.variable_a)  # -&amp;gt; 1&lt;br /&gt;
print(instance_b.variable_a)  # -&amp;gt; 2&amp;lt;/syntaxhighlight&amp;gt;In this example we create an instance with &amp;#039;&amp;#039;&amp;#039;SimpleClass()&amp;#039;&amp;#039;&amp;#039; . Reading the content of the ( ) it depends on how you define the method __init__ . By default it doesn’t take any arguments from you.&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
Code and data are the components a class is made of. Let us look at the data (i.e. variables) first. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: If we want to use a variable (or a method) of the class from within the class we need to use the prefix self.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== BEST (in my opinion) ===&lt;br /&gt;
To make a long story short, you want to do it like this:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class MostSimplestClass:&lt;br /&gt;
    a: int&lt;br /&gt;
    b: list&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.a = 0&lt;br /&gt;
        self.b = []&amp;lt;/syntaxhighlight&amp;gt;or use direclty a dataclass when possible!&lt;br /&gt;
&lt;br /&gt;
=== BAD: How we DON’T want to do it ===&lt;br /&gt;
We have the option to add variables from outside to the class:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class MostSimplestClass:&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
instance = MostSimplestClass()&lt;br /&gt;
instance.a: int = 1&lt;br /&gt;
print(instance.a)&amp;lt;/syntaxhighlight&amp;gt;or you can define variables in any of the methods:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class MostSimplestClass:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.a: int = 1&lt;br /&gt;
&lt;br /&gt;
    def first_run(self):&lt;br /&gt;
        self.b: int = 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = MostSimplestClass()&lt;br /&gt;
print(instance.a) # -&amp;gt; 1&lt;br /&gt;
instance.first_run()&lt;br /&gt;
print(instance.b) # -&amp;gt; 2&amp;lt;/syntaxhighlight&amp;gt;This is valid and working code. However, you will create a mess. If someone else (or yourself after a few weeks later) needs to look at your source code, there will be tears and hate.  &lt;br /&gt;
&lt;br /&gt;
Better, but not good, is to define everything in __init__():&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class MostSimplestClass:&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.a: int = 1&lt;br /&gt;
        self.b: int = 0&lt;br /&gt;
&lt;br /&gt;
    def first_run(self):&lt;br /&gt;
        self.b = 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = MostSimplestClass()&lt;br /&gt;
print(instance.a)  # -&amp;gt; 1&lt;br /&gt;
instance.first_run()&lt;br /&gt;
print(instance.b)  # -&amp;gt; 2&amp;lt;/syntaxhighlight&amp;gt;However, if your __init__ is more complex, you have to search through it for finding the variables. &lt;br /&gt;
&lt;br /&gt;
=== GOOD ===&lt;br /&gt;
For a better code quality we should look at the Python dataclass. &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class MostSimplestClass:&lt;br /&gt;
    a: int = 1&lt;br /&gt;
    b: int = 0&lt;br /&gt;
&lt;br /&gt;
    def first_run(self):&lt;br /&gt;
        self.b = 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = MostSimplestClass()&lt;br /&gt;
print(instance.a)  # -&amp;gt; 1&lt;br /&gt;
instance.first_run()&lt;br /&gt;
print(instance.b)  # -&amp;gt; 2&amp;lt;/syntaxhighlight&amp;gt;Now every class variable is defined in the beginning at one place. Easy to find. Easy to look through. We also add the type of the variable here, since we should provide it at the first use of the variable. All question or uncertainty where the first appearance of a variable will be is removed. &lt;br /&gt;
&lt;br /&gt;
However, we need to talk about [https://docs.python.org/3/glossary.html#term-mutable mutable objects] and [https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables the problem with mutable objects] and their initialization.&lt;br /&gt;
&lt;br /&gt;
=== The danger of initializing mutable variables ===&lt;br /&gt;
&lt;br /&gt;
* [https://docs.python.org/3/glossary.html#term-immutable immutable] (e.g. numbers, string, tuples) : “An object with a fixed value. Immutable objects include numbers, strings and tuples. Such an object cannot be altered. A new object has to be created if a different value has to be stored.”&lt;br /&gt;
* [https://docs.python.org/3/glossary.html#term-mutable mutable] ([https://docs.python.org/3/tutorial/introduction.html#lists list], [https://docs.python.org/3/tutorial/datastructures.html#dictionaries dictionary], [https://docs.python.org/3/tutorial/datastructures.html#sets set]) : “Mutable objects can change their value but keep their [https://docs.python.org/3/library/functions.html#id id()].”&lt;br /&gt;
&lt;br /&gt;
This is how the problem looks like:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    a: int = 0&lt;br /&gt;
    b: list = []&lt;br /&gt;
&lt;br /&gt;
instance_a = SimpleClass()&lt;br /&gt;
instance_b = SimpleClass()&lt;br /&gt;
&lt;br /&gt;
instance_a.a = 1&lt;br /&gt;
print(instance_a.a)  # -&amp;gt; 1&lt;br /&gt;
print(instance_b.a)  # -&amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
instance_a.b.append(&amp;quot;X&amp;quot;)&lt;br /&gt;
print(instance_a.b)  # -&amp;gt; [&amp;#039;X&amp;#039;]&lt;br /&gt;
print(instance_b.b)  # -&amp;gt; [&amp;#039;X&amp;#039;]&amp;lt;/syntaxhighlight&amp;gt;The correct way to handle it is:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    a: int&lt;br /&gt;
    b: list&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.a = 0&lt;br /&gt;
        self.b = []&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance_a = SimpleClass()&lt;br /&gt;
instance_b = SimpleClass()&lt;br /&gt;
&lt;br /&gt;
instance_a.a = 1&lt;br /&gt;
print(instance_a.a)  # -&amp;gt; 1&lt;br /&gt;
print(instance_b.a)  # -&amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
instance_a.b.append(&amp;quot;X&amp;quot;)&lt;br /&gt;
print(instance_a.b)  # -&amp;gt; [&amp;#039;X&amp;#039;]&lt;br /&gt;
print(instance_b.b)  # -&amp;gt; []&amp;lt;/syntaxhighlight&amp;gt;Since you have defined the variables in the beginning of the class and know the type of it (due to the type annotation), you can just copy the list into the constructor __init__ and initialize the variables there. &lt;br /&gt;
&lt;br /&gt;
=== The alternative: dataclass ===&lt;br /&gt;
Maybe you want to consider using dataclass where it is possible instead. There you are protected against this error:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from dataclasses import dataclass&lt;br /&gt;
&lt;br /&gt;
@dataclass&lt;br /&gt;
class SimpleClass:&lt;br /&gt;
    a: list = [] &amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;ValueError: mutable default &amp;lt;class &amp;#039;list&amp;#039;&amp;gt; for field a is not allowed: use default_factory&amp;lt;/syntaxhighlight&amp;gt;And you get there a nice way to initialize mutable objects safely via default_factory: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from dataclasses import dataclass, field&lt;br /&gt;
&lt;br /&gt;
@dataclass&lt;br /&gt;
class SimpleClass:&lt;br /&gt;
    a: list = field(default_factory=list)&lt;br /&gt;
&lt;br /&gt;
instance_a = SimpleClass()&lt;br /&gt;
instance_b = SimpleClass()&lt;br /&gt;
&lt;br /&gt;
instance_a.a.append(&amp;quot;X&amp;quot;)&lt;br /&gt;
print(instance_a.a)  # -&amp;gt; [&amp;#039;X&amp;#039;]&lt;br /&gt;
print(instance_b.a)  # -&amp;gt; []&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/library/functions.html#property @property()] ===&lt;br /&gt;
{: .topic-optional} This is an optional topic!&lt;br /&gt;
&lt;br /&gt;
If a variable starts with one _ this tells us that it is “private” and we shouldn’t touch it directly with our dirty hands from the outside. However, we can use @property to control the communication with the outside world:  &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    _a: int = 0&lt;br /&gt;
&lt;br /&gt;
    @property&lt;br /&gt;
    def a(self) -&amp;gt; int:&lt;br /&gt;
        return self._a&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
&lt;br /&gt;
print(instance.a)  &lt;br /&gt;
&lt;br /&gt;
instance.a = 1  &amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;0&lt;br /&gt;
[...]&lt;br /&gt;
AttributeError: property &amp;#039;a&amp;#039; of &amp;#039;SimpleClass&amp;#039; object has no setter&amp;lt;/syntaxhighlight&amp;gt;If we want to then we can allow writing and deleting of the variable too:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    _variablename: int = 0&lt;br /&gt;
&lt;br /&gt;
    @property&lt;br /&gt;
    def variablename(self) -&amp;gt; int:&lt;br /&gt;
        return self._variablename&lt;br /&gt;
&lt;br /&gt;
    @variablename.setter&lt;br /&gt;
    def variablename(self, value):&lt;br /&gt;
        self._variablename = value&lt;br /&gt;
&lt;br /&gt;
    @variablename.deleter&lt;br /&gt;
    def variablename(self):&lt;br /&gt;
        del self._variablename&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
&lt;br /&gt;
print(instance.variablename)  # -&amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
instance.variablename = 1&lt;br /&gt;
print(instance.variablename)  # -&amp;gt; 1&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/reference/datamodel.html#slots __slots__] ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[https://docs.python.org/3/reference/datamodel.html#slots They say:]&lt;br /&gt;
&lt;br /&gt;
* __slots__ allow us to explicitly declare data members (like properties) and deny the creation of [https://docs.python.org/3/library/stdtypes.html#object.__dict__ __dict__] and __weakref__ (unless explicitly declared in __slots__ or available in a parent.) The space saved over using [https://docs.python.org/3/library/stdtypes.html#object.__dict__ __dict__] can be significant. Attribute lookup speed can be significantly improved as well. Let’s test if they are really smaller (Note: I will use the memory_profiler module which doesn’t work with ipython: pip install memory_profiler ): &lt;br /&gt;
&lt;br /&gt;
With slots:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from memory_profiler import profile&lt;br /&gt;
&lt;br /&gt;
class SimpleClass:&lt;br /&gt;
    __slots__ = [&amp;quot;variable_a&amp;quot;, &amp;quot;variable_b&amp;quot;, &amp;quot;variable_c&amp;quot;]&lt;br /&gt;
    variable_a: int&lt;br /&gt;
    variable_b: float&lt;br /&gt;
    variable_c: float&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, value) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = value&lt;br /&gt;
        self.variable_b = value * 2&lt;br /&gt;
        self.variable_c = value * 3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@profile&lt;br /&gt;
def main():&lt;br /&gt;
    instances = []&lt;br /&gt;
    for i in range(0, 100000):&lt;br /&gt;
        instances.append(SimpleClass(i))&lt;br /&gt;
&lt;br /&gt;
main()&amp;lt;/syntaxhighlight&amp;gt;Note: The default values are set in the __init__ and in the section not above. __slots__ doesn’t like it if you provide directly default values. &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;Line #    Mem usage    Increment  Occurrences   Line Contents&lt;br /&gt;
=============================================================&lt;br /&gt;
    17     39.2 MiB     39.2 MiB           1   @profile&lt;br /&gt;
    18                                         def main():&lt;br /&gt;
    19     39.2 MiB      0.0 MiB           1       instances = []&lt;br /&gt;
    20     56.0 MiB     13.9 MiB      100001       for i in range(0, 100000):&lt;br /&gt;
    21     56.0 MiB      2.8 MiB      100000           instances.append(SimpleClass(i))&amp;lt;/syntaxhighlight&amp;gt;Without slots:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from memory_profiler import profile&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
    variable_b: float&lt;br /&gt;
    variable_c: float&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, value) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = value&lt;br /&gt;
        self.variable_b = value * 2&lt;br /&gt;
        self.variable_c = value * 3&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@profile&lt;br /&gt;
def main():&lt;br /&gt;
    instances = []&lt;br /&gt;
    for i in range(0, 100000):&lt;br /&gt;
        instances.append(SimpleClass(i))&lt;br /&gt;
&lt;br /&gt;
main()&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;Line #    Mem usage    Increment  Occurrences   Line Contents&lt;br /&gt;
=============================================================&lt;br /&gt;
    17     39.4 MiB     39.4 MiB           1   @profile&lt;br /&gt;
    18                                         def main():&lt;br /&gt;
    19     39.4 MiB      0.0 MiB           1       instances = []&lt;br /&gt;
    20     65.2 MiB      6.2 MiB      100001       for i in range(0, 100000):&lt;br /&gt;
    21     65.2 MiB     19.6 MiB      100000           instances.append(SimpleClass(i))&amp;lt;/syntaxhighlight&amp;gt;Why don’t we use it all the time? Well, dynamic maneuvers like this are now denied:  &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    __slots__ = [&amp;quot;variable_a&amp;quot;, &amp;quot;variable_b&amp;quot;, &amp;quot;variable_c&amp;quot;]&lt;br /&gt;
    variable_a: int&lt;br /&gt;
    variable_b: float&lt;br /&gt;
    variable_c: float&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, value) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = value&lt;br /&gt;
        self.variable_b = value * 2&lt;br /&gt;
        self.variable_c = value * 3&lt;br /&gt;
        self.b = 1 # AttributeError: &amp;#039;SimpleClass&amp;#039; object has no attribute &amp;#039;b&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instances = SimpleClass(1)&lt;br /&gt;
instances.a = 1  # AttributeError: &amp;#039;SimpleClass&amp;#039; object has no attribute &amp;#039;a&amp;#039;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: If we want to use a method (or a variable) of the class from within the class we need to use the prefix self.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
In this example we have defined two methods: &amp;#039;&amp;#039;&amp;#039;__init__&amp;#039;&amp;#039;&amp;#039; which is the constructor and &amp;#039;&amp;#039;&amp;#039;some_method&amp;#039;&amp;#039;&amp;#039; . Methods are “just” functions defined in a class. &lt;br /&gt;
&lt;br /&gt;
Typically (except you deal with @classmethod or @staticmethod) the first argument of a method is &amp;#039;&amp;#039;&amp;#039;self&amp;#039;&amp;#039;&amp;#039;.&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = 1&lt;br /&gt;
&lt;br /&gt;
    def some_method(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return self.variable_a + input&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
print(instance.some_method(678)) # -&amp;gt; 679&amp;lt;/syntaxhighlight&amp;gt;In case we use a function from the outside of the class, we don’t see / provide &amp;#039;&amp;#039;&amp;#039;self&amp;#039;&amp;#039;&amp;#039; as an input argument.&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = 1&lt;br /&gt;
&lt;br /&gt;
    def some_method(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return self.variable_a + input&lt;br /&gt;
&lt;br /&gt;
    def some_other_method(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return self.some_method(input)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
print(instance.some_other_method(678))  # -&amp;gt; 679&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/reference/datamodel.html#object.__init__ Constructor: __init__] ===&lt;br /&gt;
When we [https://docs.python.org/3/reference/datamodel.html#object.__init__ create] a new instance, two internal functions of the class are called __new__ and __init__ . __new__ creates it and __init__ customize it. Normally there is no reason to touch __new__.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note: No return values except None are allowed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We will otherwise get errors like: “TypeError: __init__() should return None, not ‘int’”&lt;br /&gt;
&lt;br /&gt;
The first parameter of __init__ is always &amp;#039;&amp;#039;&amp;#039;self&amp;#039;&amp;#039;&amp;#039;!&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = 1&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&amp;lt;/syntaxhighlight&amp;gt;We can add more arguments if we want to. Here an example with one additional argument: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, value) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = value&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass(1)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/reference/datamodel.html#object.__str__ __str__] and [https://docs.python.org/3/reference/datamodel.html#object.__repr__ __repr__] ===&lt;br /&gt;
If we print our class then this happens:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, value) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = value&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass(1)&lt;br /&gt;
print(instance) # -&amp;gt; &amp;lt;__main__.SimpleClass object at 0x7fcab0600b80&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;However, we can add a __str__ function and then we can customize our output:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    variable_a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, value) -&amp;gt; None:&lt;br /&gt;
        self.variable_a = value&lt;br /&gt;
&lt;br /&gt;
    def __str__(self) -&amp;gt; str:&lt;br /&gt;
        return f&amp;quot;{self.variable_a}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass(1)&lt;br /&gt;
print(instance)&amp;lt;/syntaxhighlight&amp;gt;But please be aware that there are more than one putative functions for producing output information: &lt;br /&gt;
&lt;br /&gt;
* [https://docs.python.org/3/reference/datamodel.html#object.__str__ object.__str__(self)] &amp;#039;&amp;#039;&amp;#039;human friendly&amp;#039;&amp;#039;&amp;#039; : Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.&lt;br /&gt;
* [https://docs.python.org/3/reference/datamodel.html#object.__repr__ object.__repr__(self)]  &amp;#039;&amp;#039;&amp;#039;unambiguous&amp;#039;&amp;#039;&amp;#039; : Called by the repr() built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form &amp;amp;#x3C;…some useful description…&amp;amp;#x3E; should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required. This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/library/functions.html#staticmethod @staticmethod] and [https://docs.python.org/3/library/functions.html#classmethod @classmethod] ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Let us be blunt here: I am not sure if you want/ need to know what @staticmethod and @classmethod does.&amp;#039;&amp;#039;&amp;#039; I was interested in this topic because I saw these decorators and asked myself what they are for. &lt;br /&gt;
&lt;br /&gt;
This is a normal class method: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    def normal_class_method(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return input&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
x = instance.normal_class_method(123)&lt;br /&gt;
print(x) # -&amp;gt; 123&lt;br /&gt;
&lt;br /&gt;
print(instance.normal_class_method)  # -&amp;gt; &amp;lt;bound method SimpleClass.normal_class_method of &amp;lt;__main__.SimpleClass object at 0x7fcaac3334c0&amp;gt;&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;The normal class method is bound (i.e. connected) to its class. &lt;br /&gt;
&lt;br /&gt;
In the case of a &amp;#039;&amp;#039;&amp;#039;@staticmethod&amp;#039;&amp;#039;&amp;#039;, it has no first argument self. And it is not bound to the class. Or in other words: The class is just a container for this @staticmethod or “regular” function. &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    @staticmethod&lt;br /&gt;
    def static_class_method(input: int) -&amp;gt; int:&lt;br /&gt;
        return input&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
x = instance.static_class_method(123)&lt;br /&gt;
print(x)  # -&amp;gt; 123&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    instance.static_class_method&lt;br /&gt;
)  # -&amp;gt; &amp;lt;function SimpleClass.static_class_method at 0x7fca969036d0&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;In the case of a &amp;#039;&amp;#039;&amp;#039;@classmethod&amp;#039;&amp;#039;&amp;#039;, we generate a function that can be called via the class and NOT via the instance: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class SimpleClass:&lt;br /&gt;
    @classmethod&lt;br /&gt;
    def class_class_method(cls, input: int) -&amp;gt; int:&lt;br /&gt;
        return input&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
x = SimpleClass.class_class_method(123)&lt;br /&gt;
print(x)  # -&amp;gt; 123&amp;lt;/syntaxhighlight&amp;gt;Note: cls is the replacement for self here. cls gives the class and self the instance to the function. &lt;br /&gt;
&lt;br /&gt;
== Inherentence ==&lt;br /&gt;
Inherentence allows us to add on variables and/or methods to a existing class without copying the whole source code. We inherent from a class if the put it into ( ) in the class definition:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    a: int = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ClassA(BaseClassA):&lt;br /&gt;
    b: int = 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = ClassA()&lt;br /&gt;
print(instance.a)  # -&amp;gt; 0&lt;br /&gt;
print(instance.b)  # -&amp;gt; 1&amp;lt;/syntaxhighlight&amp;gt;Also we can replace functions:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(&amp;quot;BaseClassA&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ClassA(BaseClassA):&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(&amp;quot;ClassA&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = ClassA()&lt;br /&gt;
instance.print_something() # -&amp;gt; ClassA&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multiple inheritance ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
And we inherent from more than one class: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(&amp;quot;BaseClassA&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassB:&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(&amp;quot;BaseClassB&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ClassA(BaseClassA, BaseClassB):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ClassB(BaseClassB, BaseClassA):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance_a = ClassA()&lt;br /&gt;
instance_a.print_something()  # -&amp;gt; BaseClassA&lt;br /&gt;
instance_b = ClassB()&lt;br /&gt;
instance_b.print_something()  # -&amp;gt; BaseClassB&lt;br /&gt;
&lt;br /&gt;
print(ClassA.__mro__) # -&amp;gt; (&amp;lt;class &amp;#039;__main__.ClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassB&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;object&amp;#039;&amp;gt;)&lt;br /&gt;
print(ClassB.__mro__) # -&amp;gt; (&amp;lt;class &amp;#039;__main__.ClassB&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassB&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;__main__.BaseClassA&amp;#039;&amp;gt;, &amp;lt;class &amp;#039;object&amp;#039;&amp;gt;)&amp;lt;/syntaxhighlight&amp;gt;As you can see: Which version of the functions survives can be complicated. If you want to understand the MRO (Method resolution order) you can look up [[wikipedia:C3_linearization|C3 linearization]]. Personally, I would try to avoid this unclear situations everywhere. &lt;br /&gt;
&lt;br /&gt;
We can define more precisely and prevent surprises: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    a = 1&lt;br /&gt;
&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(f&amp;quot;BaseClassA {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassB:&lt;br /&gt;
    a = 2&lt;br /&gt;
&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(f&amp;quot;BaseClassB {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class ClassA(BaseClassA, BaseClassB):&lt;br /&gt;
    a = 3&lt;br /&gt;
&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        BaseClassB.print_something(self)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance_a = ClassA()&lt;br /&gt;
instance_a.print_something() # -&amp;gt; BaseClassB 3&amp;lt;/syntaxhighlight&amp;gt;If we only inherent from one class we can use super().&lt;br /&gt;
&lt;br /&gt;
== [https://docs.python.org/3/library/functions.html#super super()] ==&lt;br /&gt;
&lt;br /&gt;
* “There are two typical use cases for super. In a class hierarchy with single inheritance, super can be used to refer to parent classes without naming them explicitly, thus making the code more maintainable. This use closely parallels the use of super in other programming languages.”&lt;br /&gt;
* “The second use case is to support cooperative multiple inheritance in a dynamic execution environment.”&lt;br /&gt;
&lt;br /&gt;
Or in other words: super() will call the version of a function that is next in line in the MRO. &lt;br /&gt;
&lt;br /&gt;
As a simple example lets look at BaseClassA -&amp;amp;#x3E; BaseClassB -&amp;amp;#x3E; BaseClassC: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    a = 1&lt;br /&gt;
&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        print(f&amp;quot;BaseClassA {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassB(BaseClassA):&lt;br /&gt;
    a = 2&lt;br /&gt;
&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        super().print_something()&lt;br /&gt;
        print(f&amp;quot;BaseClassB {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassC(BaseClassB):&lt;br /&gt;
    a = 3&lt;br /&gt;
&lt;br /&gt;
    def print_something(self):&lt;br /&gt;
        super().print_something()&lt;br /&gt;
        print(f&amp;quot;BaseClassC {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance_a = BaseClassC()&lt;br /&gt;
instance_a.print_something()&amp;lt;/syntaxhighlight&amp;gt;Output&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;BaseClassA 3&lt;br /&gt;
BaseClassB 3&lt;br /&gt;
BaseClassC 3&amp;lt;/syntaxhighlight&amp;gt;Note that for BaseClassA there is no super() because there is no higher level to call. But in the case of __init__ we can do that:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    a = 1&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        print(f&amp;quot;BaseClassA {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassB(BaseClassA):&lt;br /&gt;
    a = 2&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        print(f&amp;quot;BaseClassB {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassC(BaseClassB):&lt;br /&gt;
    a = 3&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        print(f&amp;quot;BaseClassC {self.a}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance_a = BaseClassC()&amp;lt;/syntaxhighlight&amp;gt;Output&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;BaseClassA 3&lt;br /&gt;
BaseClassB 3&lt;br /&gt;
BaseClassC 3&amp;lt;/syntaxhighlight&amp;gt;Why can we do that? Well, &amp;#039;&amp;#039;&amp;#039;class BaseClassA&amp;#039;&amp;#039;&amp;#039;: is just a shorthand for &amp;#039;&amp;#039;&amp;#039;class BaseClassA(object)&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
[https://docs.python.org/3/reference/datamodel.html#basic-customization Object] already provides us with some basic functionality like __init__ which is contained in all user custom classes (if not removed). &lt;br /&gt;
&lt;br /&gt;
== [https://docs.python.org/3/library/abc.html#module-abc ABC (Abstract Base Classes)] and [https://docs.python.org/3/library/abc.html#abc.abstractmethod @abstractmethod] ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Maybe you need a placeholder for a future function but also want to make REALLY sure that the new class defines the function. For such a case you can use the base class ABC with @abstractmethod&lt;br /&gt;
&lt;br /&gt;
Deliberately not working:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from abc import ABC, abstractmethod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassA(ABC):&lt;br /&gt;
    @abstractmethod&lt;br /&gt;
    def function_a(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = BaseClassA() # -&amp;gt; TypeError: Can&amp;#039;t instantiate abstract class BaseClassA with abstract method function_a&amp;lt;/syntaxhighlight&amp;gt;Also deliberately not working:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from abc import ABC, abstractmethod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassA(ABC):&lt;br /&gt;
    @abstractmethod&lt;br /&gt;
    def function_a(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassB(BaseClassA):&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
instance = BaseClassB() # TypeError: Can&amp;#039;t instantiate abstract class BaseClassB with abstract method function_a&amp;lt;/syntaxhighlight&amp;gt;This is working:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from abc import ABC, abstractmethod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassA(ABC):&lt;br /&gt;
    @abstractmethod&lt;br /&gt;
    def function_a(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseClassB(BaseClassA):&lt;br /&gt;
    def function_a(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = BaseClassB()&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compositions – Against the curse of dimensionality ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
While inherentence is a nice tool, it leads very fast to an explosion of specialized classes.&lt;br /&gt;
&lt;br /&gt;
An alternative is the composition approach. Here a base class for a functionality is prepared with the required abstract placeholders. This base class is then inherented by classes that provide the required spectrum of functionality. Then a composition class is designed. During instancing the composition class we plug in the functionality we want. &lt;br /&gt;
&lt;br /&gt;
Hard to explain in words. Easy to show in an example: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from abc import ABC, abstractmethod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class BaseFunction(ABC):&lt;br /&gt;
    @abstractmethod&lt;br /&gt;
    def add_something(self, input: int) -&amp;gt; int:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class AddOne(BaseFunction):&lt;br /&gt;
    def add_something(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return input + 1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class AddTwo(BaseFunction):&lt;br /&gt;
    def add_something(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return input + 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CompositionClass:&lt;br /&gt;
    method_one: BaseFunction&lt;br /&gt;
    method_two: BaseFunction&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, method_one: BaseFunction, method_two: BaseFunction) -&amp;gt; None:&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.method_one = method_one&lt;br /&gt;
        self.method_two = method_two&lt;br /&gt;
&lt;br /&gt;
    def processing(self, input: int) -&amp;gt; int:&lt;br /&gt;
        return self.method_two.add_something(self.method_one.add_something(input))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
variant_a = CompositionClass(method_one=AddOne(), method_two=AddOne())&lt;br /&gt;
print(variant_a.processing(0))  # -&amp;gt; 2&lt;br /&gt;
&lt;br /&gt;
variant_b = CompositionClass(method_one=AddTwo(), method_two=AddTwo())&lt;br /&gt;
print(variant_b.processing(0))  # -&amp;gt; 4&lt;br /&gt;
&lt;br /&gt;
variant_c = CompositionClass(method_one=AddOne(), method_two=AddTwo())&lt;br /&gt;
print(variant_c.processing(0))  # -&amp;gt; 3&lt;br /&gt;
&lt;br /&gt;
variant_d = CompositionClass(method_one=AddTwo(), method_two=AddOne())&lt;br /&gt;
print(variant_d.processing(0))  # -&amp;gt; 3&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [https://docs.python.org/3/library/functools.html functools] ==&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/library/functools.html#functools.cached_property @cached_property] (not recommended) ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
I am not really a fan of this one. It allows you to cache calculations. However, this works only if the data behind the calculation doesn’t change in any way, shape or form. If you change it then result is NOT updated. &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from functools import cached_property&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class SimpleClass:&lt;br /&gt;
    _a: int&lt;br /&gt;
    _b: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self._a = 1&lt;br /&gt;
        self._b = 2&lt;br /&gt;
&lt;br /&gt;
    @cached_property&lt;br /&gt;
    def value_x(self):&lt;br /&gt;
        return self._a + self._b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
print(instance.value_x)  # -&amp;gt; 3&lt;br /&gt;
instance._a = 7&lt;br /&gt;
print(instance.value_x)  # -&amp;gt; 3&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [https://docs.python.org/3/library/functools.html#functools.partialmethod partialmethod] ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Partialmethod allows you to create an alias for an already defined function but with partially pre-defined arguments:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;from functools import partialmethod&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class SimpleClass:&lt;br /&gt;
    def function_a(self, input_1: int, input_2: int) -&amp;gt; int:&lt;br /&gt;
        return input_1 + input_2&lt;br /&gt;
&lt;br /&gt;
    add_one = partialmethod(function_a, 1)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = SimpleClass()&lt;br /&gt;
&lt;br /&gt;
print(instance.function_a(1, 1))  # -&amp;gt; 2&lt;br /&gt;
print(instance.add_one(1))  # -&amp;gt; 2&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[pythoninfo:Iterator|Iterators]] ==&lt;br /&gt;
Iterators are used in e.g. for loops. Iterators are classes that provide the methods [https://docs.python.org/3/reference/datamodel.html#object.__iter__ __iter__] and [https://docs.python.org/3/library/stdtypes.html#iterator.__next__ __next__] . __iter__ just returns itself. __next__ does something. If __next__ can not do anything more (e.g. because there is not more data) then it raises the exception StopIteration.&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class IterExample:&lt;br /&gt;
    a_max: int&lt;br /&gt;
    a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.a_max = 10&lt;br /&gt;
        self.a = 0&lt;br /&gt;
&lt;br /&gt;
    def __iter__(self):&lt;br /&gt;
        return self&lt;br /&gt;
&lt;br /&gt;
    def __next__(self):&lt;br /&gt;
        if self.a &amp;lt; self.a_max:&lt;br /&gt;
            self.a += 1&lt;br /&gt;
        else:&lt;br /&gt;
            raise StopIteration&lt;br /&gt;
        return self.a**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = IterExample()&lt;br /&gt;
&lt;br /&gt;
for i in instance:&lt;br /&gt;
    print(i)&amp;lt;/syntaxhighlight&amp;gt;We can also use the iterator class manually via [https://docs.python.org/3/library/functions.html#next next()]:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class IterExample:&lt;br /&gt;
    a_max: int&lt;br /&gt;
    a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        self.a_max = 10&lt;br /&gt;
        self.a = 0&lt;br /&gt;
&lt;br /&gt;
    def __iter__(self):&lt;br /&gt;
        return self&lt;br /&gt;
&lt;br /&gt;
    def __next__(self):&lt;br /&gt;
        if self.a &amp;lt; self.a_max:&lt;br /&gt;
            self.a += 1&lt;br /&gt;
        else:&lt;br /&gt;
            raise StopIteration&lt;br /&gt;
        return self.a**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = IterExample()&lt;br /&gt;
&lt;br /&gt;
print(next(instance))  # -&amp;gt; 1&lt;br /&gt;
print(next(instance))  # -&amp;gt; 4&lt;br /&gt;
print(next(instance))  # -&amp;gt; 9&lt;br /&gt;
print(next(instance))  # -&amp;gt; 16&lt;br /&gt;
print(next(instance))  # -&amp;gt; 25&lt;br /&gt;
print(next(instance))  # -&amp;gt; 36&lt;br /&gt;
print(next(instance))  # -&amp;gt; 49&lt;br /&gt;
print(next(instance))  # -&amp;gt; 64&lt;br /&gt;
print(next(instance))  # -&amp;gt; 81&lt;br /&gt;
print(next(instance))  # -&amp;gt; 100&lt;br /&gt;
print(next(instance))  # -&amp;gt; StopIteration:&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [https://docs.python.org/3/glossary.html#term-generator Generators] ==&lt;br /&gt;
“A function which returns a [https://docs.python.org/3/glossary.html#term-generator-iterator generator iterator]. It looks like a normal function except that it contains [https://docs.python.org/3/reference/simple_stmts.html#yield yield] expressions for producing a series of values usable in a for-loop or that can be retrieved one at a time with the [https://docs.python.org/3/library/functions.html#next next()] function.”&lt;br /&gt;
&lt;br /&gt;
Manually:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def generator(start_value: int, end_value: int):&lt;br /&gt;
    for i in range(start_value, end_value):&lt;br /&gt;
        yield i**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
i = iter(generator(1, 11))&lt;br /&gt;
&lt;br /&gt;
print(next(i))  # -&amp;gt; 1&lt;br /&gt;
print(next(i))  # -&amp;gt; 4&lt;br /&gt;
print(next(i))  # -&amp;gt; 9&lt;br /&gt;
print(next(i))  # -&amp;gt; 16&lt;br /&gt;
print(next(i))  # -&amp;gt; 25&lt;br /&gt;
print(next(i))  # -&amp;gt; 36&lt;br /&gt;
print(next(i))  # -&amp;gt; 49&lt;br /&gt;
print(next(i))  # -&amp;gt; 64&lt;br /&gt;
print(next(i))  # -&amp;gt; 81&lt;br /&gt;
print(next(i))  # -&amp;gt; 100&lt;br /&gt;
print(next(i))  # -&amp;gt; StopIteration:&amp;lt;/syntaxhighlight&amp;gt;Via for-loop:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;def generator(start_value: int, end_value: int):&lt;br /&gt;
    for i in range(start_value, end_value):&lt;br /&gt;
        yield i**2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for i in generator(1, 11):&lt;br /&gt;
    print(i)&amp;lt;/syntaxhighlight&amp;gt;Output:&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;1&lt;br /&gt;
4&lt;br /&gt;
9&lt;br /&gt;
16&lt;br /&gt;
25&lt;br /&gt;
36&lt;br /&gt;
49&lt;br /&gt;
64&lt;br /&gt;
81&lt;br /&gt;
100&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [https://docs.python.org/3/library/functions.html#dir dir] ==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;This is an optional topic!&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
“Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.”&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.a = 1&lt;br /&gt;
&lt;br /&gt;
    def function_a(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def function_b(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
print(dir(BaseClassA))&amp;lt;/syntaxhighlight&amp;gt;Output&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;[&amp;#039;__annotations__&amp;#039;, &amp;#039;__class__&amp;#039;, &amp;#039;__delattr__&amp;#039;, &amp;#039;__dict__&amp;#039;, &amp;#039;__dir__&amp;#039;, &amp;#039;__doc__&amp;#039;, &amp;#039;__eq__&amp;#039;, &amp;#039;__format__&amp;#039;, &amp;#039;__ge__&amp;#039;, &amp;#039;__getattribute__&amp;#039;, &amp;#039;__gt__&amp;#039;, &amp;#039;__hash__&amp;#039;, &amp;#039;__init__&amp;#039;, &amp;#039;__init_subclass__&amp;#039;, &amp;#039;__le__&amp;#039;, &amp;#039;__lt__&amp;#039;, &amp;#039;__module__&amp;#039;, &amp;#039;__ne__&amp;#039;, &amp;#039;__new__&amp;#039;, &amp;#039;__reduce__&amp;#039;, &amp;#039;__reduce_ex__&amp;#039;, &amp;#039;__repr__&amp;#039;, &amp;#039;__setattr__&amp;#039;, &amp;#039;__sizeof__&amp;#039;, &amp;#039;__str__&amp;#039;, &amp;#039;__subclasshook__&amp;#039;, &amp;#039;__weakref__&amp;#039;, &amp;#039;function_a&amp;#039;, &amp;#039;function_b&amp;#039;]&amp;lt;/syntaxhighlight&amp;gt;If you look carefully through the list you will notice that the variable a is not there. The reason for this is that it doesn’t exist until the instance is created:  &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;class BaseClassA:&lt;br /&gt;
    __slots__ = [&amp;quot;a&amp;quot;]&lt;br /&gt;
    a: int&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        super().__init__()&lt;br /&gt;
        self.a = 1&lt;br /&gt;
&lt;br /&gt;
    def function_a(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    def function_b(self):&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
instance = BaseClassA()&lt;br /&gt;
print(dir(instance))&amp;lt;/syntaxhighlight&amp;gt;Output&lt;br /&gt;
&lt;br /&gt;
Even with __slots__ use, now the variable a is included in the list: &amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;[&amp;#039;__annotations__&amp;#039;, &amp;#039;__class__&amp;#039;, &amp;#039;__delattr__&amp;#039;, &amp;#039;__dir__&amp;#039;, &amp;#039;__doc__&amp;#039;, &amp;#039;__eq__&amp;#039;, &amp;#039;__format__&amp;#039;, &amp;#039;__ge__&amp;#039;, &amp;#039;__getattribute__&amp;#039;, &amp;#039;__gt__&amp;#039;, &amp;#039;__hash__&amp;#039;, &amp;#039;__init__&amp;#039;, &amp;#039;__init_subclass__&amp;#039;, &amp;#039;__le__&amp;#039;, &amp;#039;__lt__&amp;#039;, &amp;#039;__module__&amp;#039;, &amp;#039;__ne__&amp;#039;, &amp;#039;__new__&amp;#039;, &amp;#039;__reduce__&amp;#039;, &amp;#039;__reduce_ex__&amp;#039;, &amp;#039;__repr__&amp;#039;, &amp;#039;__setattr__&amp;#039;, &amp;#039;__sizeof__&amp;#039;, &amp;#039;__slots__&amp;#039;, &amp;#039;__str__&amp;#039;, &amp;#039;__subclasshook__&amp;#039;, &amp;#039;a&amp;#039;, &amp;#039;function_a&amp;#039;, &amp;#039;function_b&amp;#039;]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [https://docs.python.org/3/tutorial/classes.html Classes]&lt;br /&gt;
* [https://docs.python.org/3/reference/datamodel.html#special-method-names Objects: Special method names]&lt;/div&gt;</summary>
		<author><name>Davrot</name></author>
	</entry>
</feed>