Python, as any other scripting language allows you to define variables and functions. These are very basic entities when it comes to programming. However, sometimes it is useful to keep variables and functions that are related to one-another close together. This is the main idea behind Object Oriented programming and is present in programming languages such as C++ and fortran, but also in scripting languages like java and python. In this tutorial, you can find a first brief introduction into this topic, focusing on the concept of a class.
This tutorial is part of a series of tutorials and the code is available via GitHub. As a real life example, used throughout this series, we consider a class for solving a wordle-puzzle.
1. The Python class
A class is a complex variable type, which contains specific methods (or functions) and attributes (or properties). An instance of such a complex variable is called an object, and different objects can have different values for their attributes (and even methods).
To create a class in python the class keyword is used followed by the name you want to assign your class. In our case this is the WordleAssistant class.
class WordleAssistant():
Defining attributes
This WordleAssistant contains the attributes relevant to our puzzle solver. For example, if we want to make a generic solver, two useful attributes would be the wordle word length (WordleSize) and a dictionary of possible words (FullWordset). Unlike fortran or C++, attributes are not defined in the class definition, but can be dynamically created for a class-object. This a feature (or design flaw) gives rise to some dangerous practices such as the runtime (accidental) addition of attributes to an object. For good practices, one should refrain from this and create all attributes by initializing them during the initialization of the class instance. This is done using the __init__() method of the class:
class WordleAssistant(): def __init__(self, size: int = 5, dictionary: str = None): self.WordleSize = size if dictionary is None: dictionary = "Mydict.txt" self.FullWordset = self.readDictionary(dictionary)
Here the WordleSize attribute is defined by setting it to the size parameter of the __init__ method, while the FullWordset attribute is defined by assigning it the result of the readDictionary method of the WordleAssistant class. As is common (and good) practice in OO langues we use the self variable to indicate the instance of the class, binding attributes and methods to the instance. You may also have noted python uses a dot-notation to indicate attributes/methods of a class, similar as C++ (while fortran uses the % symbol with the same effect).
!! NOTE: There also exist “class attributes” which are defined the way one would define instance attributes in fortran or C++. However, in python these attributes are shared by all instances of the class, as such changing them in one object will change them in all objects, creating a mess.
Defining methods
In the previous section, we already defined a first method, the initialization method. As a method is a function, it is constructed as any other function in python using the def keyword, with the body indented. The method itself is indented one level with respect to the class level. Similar as for a usual function, one can indicate the expected type and default value for each function parameter, and if a result is returned the type can be indicated as well, as can be seen in the example below for the readDictionary method.
class WordleAssistant(): def __init__(self, size: int = 5, dictionary: str = None): ... def readDictionary(self, wordlist: str = None)->list: ... return wordlist
Privacy
Although private attributes and methods don’t technically exist in Python, it is convention that attributes and methods prefixed with a single underscore are to be treated as non-public parts of the API. In addition, using two or more underscores gives rise to name mangling, which gives a practical behavior akin to making attributes and methods private. The __init__ method above is an example. We will come back to this when discussing inheritance and child classes.
2. The Python Object
Once the class is implemented, it can be used in a script by creating instances of the class. These instances are called Objects.
WA = WordleAssistant()
The above command creates an object WA which is of the class WordleAssistant. The object is initialized through a call to the __init__ method, which is performed by the assignment above. If defaults are provided for all parameters of the __init__ method, then no variables need to be passed to the WordleAssistant class call. Otherwise the creation of an instance could look like this:
wordleSize = 5 WA = WordleAssistant(size=wordleSize,dictionary='MyWords.txt')
Access to the attributes and methods of the WA object s gained using the dot-notation:
wordsize = WA.WordleSize wordlist = WA.FullWordset Top10Guess = WA.getTop(top = 10)
Within the context of data-encapsulation one should never access attributes directly but use get and set methods instead.