We have been exposed to Python modules or packages already: math and random are two examples. These are really a collection of variables and functions with a common theme or purpose that we can access when we need them. We don’t have to create a random number function whenever we need one, we can just use the one within random. A class than be thought of as a module.
Within the module there are functions which, because they are part of a class, are called methods. Variables can be defined within a class and have a scope all their own. A variable named x can be declared within a class and also within other classes and the main program without any confusion.
A class can be instantiated, which means an instance or version of it is created. When we say from random import * at the beginning of a program, we are effectively creating an instance of random. That’s how we get access to most of the variables and methods within it. We can instantiate random as
s = random
As an instance of random, the methods can be accessed through s using the dot notation. For example,
with print a random number. There can be multiple instances of a class, and each is created by referencing the class name.
s = random
t = random
print (s.random(), t.random())
This is not always useful, as in this case, but can be when the class contains data important to the programmer.
Variables declared inside of a class should only be accessed by using methods. If there is a variable named name within a class named client, then the variable can normally be accessed directly:
a = client # Create an instance of client.
This is considered poor form in general. We should have a get method for each variable we wish to use, and this method only returns the value of the variable:
print (a.get name())
Similarly, we will have a set method to assign values to variables within a class:
This protocol makes the class a relatively safe place. Variables can only be accessed and changed through one single method, making it correct if those methods are correct, and making all such accesses easy to locate in the code. For small programs, this matters a lot less than for larger ones, but it is always a good idea to follow this scheme.
A very important method is the constructor, which is called automatically by the system when an instance is created. This method is used to set up variables and data structures and perhaps read data at the beginning of some process. Constructors can accept parameters and then save these as local within-class variables. If a class named client has a constructor, then it is called whenever an instance is created, and the syntax of the instantiation includes a parameter list even if it is empty:
a = client() # Create an instance of client.
The idea is to provide a barrier around the methods and variables in the class. Accesses are controlled, and if the methods in the class are correct and the correct protocol is followed for using get and set methods, then it will be easier to find problems in the class, and the resulting code should be more reliable and easier to modify.
Source: Parker James R. (2021), Python: An Introduction to Programming, Mercury Learning and Information; Second edition.