Learning Python 10 minutes a day #23
A whole new class of programming

Original photo by Jeremy Lapak on Unsplash.
10 minutes a day Python crash course
Learning Python 10 minutes a day #23
A whole new class of programming
This is a series of short 10 minute Python articles helping you to boost your knowledge of Python. I try to post an article each day (no promises), starting from the very basics, going up to more complex idioms. Feel free to contact me on LinkedIn for questions or requests on particular subjects of Python you want to know about.
When getting a bit more into programming, one will come across two big paradigms: functional programming and object-oriented programming (OOP). Until now, what we mostly did is called functional programming. I have not yet found a satisfying all-round definition for both terms. However, the key difference is that functional programming, as the name suggests, centers around functions and the program structure is like a step-by-step recipe, while OOP centers around the data, which is structured in objects. It is mostly a different way of approaching a problem. There is no real good or bad between the two paradigms as there is in a preference for tennis over soccer. Sometimes, one approach seems easier for a problem, but I am convinced that you could achieve the same results with both methods. Both, OOP and the functional approach are compatible with Python.
The core idea of OOP is the abstraction of the program into objects. An object is a structure that combines the data and the code relevant to that particular piece of data. Evangelist of OOP claim that this reduces the amount of repetition and makes the code more readable. I must admit, that the idea is pretty neat and does definitely have some benefits. As a nice starter example, lets create an object for an animal and see how OOP works in Python.
[embed]
This structure does not look that difficult, but there are some new concepts. To start a class definition, you start with the class keyword, followed by a name. As a convention, class names start capitalized, but from a Python perspective, any name would be fine (but capitalize it anyway please). Similar to a function definition, we have a semicolon and all code that is indented belongs to the definition. It is good practice to provide a DocString to describe the class. In the definition itself, we can now create variables and methods. Methods are the names for functions that are in a class definition.
It is important to know the difference between the class definition and a class instance. The code we have created in the previous example starts with the class definition and creates a blueprint for our object. When we want to use that particular type of object, we need to create an instance. After the definition of our Animal class, we create two instances of that class: animal1 and animal2. While the blueprint defines which data and methods are available, it does not contain the data itself. When creating an instance of the class, we create the object that contains the actual data. In our example animal1 and animal2 are both of the type Animal but they contain different data: Frog for animal1 and Rhinoceros for animal2. You can create as many instances as you like of a previously defined class.
When creating an instance of a class, we call one of Python’s special methods: a constructor. We can see that it is special, because its name is surrounded by double-underscores. These, so called dunder-methods are given special treatment in Python. The init dunder-method indicates the constructor, a method that is called when a class instance is created. Methods can take parameters just like regular functions however, classes have one mandatory first parameter: self. Any class method in Python requires this parameter and the reason is that this particular object caries the data of the instance. When we define a class in Python, we have a reference to that class. This definition is the same for every object. To have each instance hold their own set of data such that we have a Frog and a Rhinoceros, each class has the self object, which holds the actual data. In the constructor, we define the created variables and add the data to this self object. This object is shared between the instance, but not between different instances. Now, we can use that instance data in the other methods we define in the class, such as in the description() method. This is the solution the Python developers came up with for having data at the instance level. While you can define variables at class level (something other programming languages do), this can result in unwanted results:
[embed]
This is not a bug but how Python works. The list is defined when the class is defined. Each instance gets a reference to that list and therefore, all instances share that list. This is only the case for mutable objects. immutable objects generally get a new reference when changed again, therefore, overwriting the previous reference. Just be mindful when not using the default method of defining all parameters in the constructor (which you generally should use).
[embed]
All variables that we add to the self object are accessible using the dot notation. Generally, all variables that are in an object are called attributes, while all functions are called methods. Both should have unique names and can be accessed using <object name>.<attribute name> or <object name>.<method name>() . This is the same notation as if any object in Python. Strings and integers are all objects with the same methodology. However, these classes have many more dunder-methods defined. There are special methods that take care of printing the object, if objects are add together, and if objects are multiplied. We can also define these and with those definitions make our own rules:
[embed]
The class has two more dunder-methods. The first takes care of the representation of a the class. If we would simply type the variable name representing the class instance, i.e. number1, it will call the repr dunder-method and returns it representation. This method has to return a string, but what the string is, we are free to define. The second dunder-method defines how to add two objects. It expects as a parameter, next to the mandatory self object, which is the other object. Technically, this could be any object and we have to test which type it is, before doing an addition. For now, we assume it will be of the same type. This can be any definition, even something else as we did in this example. This is very powerful as you can define objects like for example contact cards and using the add function, merge two contacts. We have seen an interesting example when we used Path from the Pathlib module. Path has the divide dunder-method defined such that it combines the path:
[embed]
For each mathematical operation, there is a dunder-method that can be defined or overloaded. Overloading means that you overwrite an existing method, which can be a regular method or one of the dunder-methods, with a new definition. There are a couple of other dunder-methods, for example for iteration related topics. It is not required to know them by hard, but definitely nice to know about their existence.
Practice for today:
Classes are great as a form of abstraction and especially suited to represent objects we know in real life. Many games need dice to play and there is a huge assortment of dice available. Some only have four faces, while others might have 100 faces.
Assignment: Create a Die class that inputs the number of faces as a parameter. It should have a throw() function to have a roll, of course using the correct die, i.e. a four-sided die can only throw 1, 2, 3, or 4. It should also contain a history() method to show the past die rolls() and a nice repr dunder function to tell us which die it is.
Hints:
- The random module as a randint(a, b) function that generates random numbers between (a, b) including both boundaries. Might be useful for dice ;-).
- You could use a list to keep track of all previous rolls.
A solution is posted on my Github.
If you have any questions, feel free to contact me through LinkedIn.
메타데이터
- post_id
- 8fd7e119da8d
- slug
- learning-python-10-minutes-a-day-23-8fd7e119da8d
- url
- https://medium.com/data-science/learning-python-10-minutes-a-day-23-8fd7e119da8d
- canonical_url
- https://medium.com/data-science/learning-python-10-minutes-a-day-23-8fd7e119da8d
- author_url
- https://medium.com/@dennisbakhuis
- status
- ok
- fetched_at
- 2026-08-10 01:20:53