Intro to Python for Makers (Part 6) - Classes and Objects
2021-06-16 | By Maker.io Staff
So far, this series discussed everything you need to begin writing Python programs. It taught you what variables are, how you can use lists, how you can write functions, and why magic methods can be helpful. However, there is more to Python than that. In the first article of this series, I mentioned that Python supports multiple programming paradigms which you can follow when writing your programs. This article discusses classes, objects, and how you can write object-oriented programs in Python.
Classes: What Are They, and How Do You Use Them in Python?
In programming, classes provide a mechanism for combining data and functionality. A class represents an entity you want to use in your program. The variables in a class characterize the entity. They act as the properties of an object. The functions of a class describe what the entity can do. They represent the skills of an object. The following code snippet contains an example of a Python class:
class Bus: vehicle_type = "Bus" def __init__(self, max_passengers=30, max_speed=80): self.max_passengers = max_passengers self.max_speed = max_speed self.passengers = [] def enter(self, passenger_name): if (len(self.passengers) + 1) <= self.max_passengers: self.passengers.append(passenger_name) return 1 else: return 0 def accelerate(self, target_speed): if target_speed <= self.max_speed: self.current_speed = target_speed def __str__(self): return "Passengers: " + str(len(self.passengers))
The example above represents a single real-world object, which is a bus in this case. You can see that the class contains a single attribute that describes the bus. All bus objects you'll ever create are going to share this single class attribute. All their vehicle_type variables will always contain the same value. If you update it in one object, the update will propagate to all other bus objects.
The bus class also contains a few functions. The first one is the __init__ method, which looks like a magic method, discussed in the last article. This special function, however, is called the class constructor. The Python interpreter invokes this function whenever you create a new object of the bus class.
Now, look inside the constructor’s parameters. You can see that the first one is called self. Naming the first parameter like this is more of a convention rather than a necessity. You may call it however you like. It refers to the current object of the class itself, and Python passes this parameter to the function automatically when required. When you create two bus objects, named b1 and b2, and then you call a method of b1, Python will automatically pass a reference to b1 to the function via the first parameter.
Note how the constructor defines a few attributes that are unique to each bus. Each individual bus object will have its own copy of the max_passengers, max_speed, and passengers variables, which may all have different values.
Note that the code within a function exists in a different scope than the code outside the method. This means that a function doesn’t automatically know that the variables outside of it exist. You, as the programmer, have to explicitly tell the function that the outside world exists. In this case, I want to assign values to class variables. Those class variables have the same names as the ones within the function. As discussed, you can use the self-keyword (or the first parameter of your class function) to indicate that you refer to a variable of the current object of the class rather than the parameter of the function. The scope restrictions apply to all methods in Python, not only the constructor.
Creating Objects
To use the newly created bus class in your program, you have to create an object of it. Objects are also known as instances of classes:
# Create two bus objects b1 = Bus() b2 = Bus(15, 100) print(“Bus 1 top speed: “ + str(b1.max_speed)) print(“Bus 2 top speed: “ + str(b2.max_speed))
Note that b1 and b2 are different instances of the same class. Like in the real world, you can have two different busses of the same make and model. In this case, I decided to change the parameters of b2. This means that b1 and b2 have different passenger capacities and varying values for their top speed:
You can now use these objects to call the functions contained within the bus class. Note how calling a method of one bus doesn’t affect the other object:
b1 = Bus() b2 = Bus(15, 100) b1.enter("Peter") b1.enter("Olivia") b1.enter("Frank") b2.enter("Hank") print(b1) print(b2)
As you can see, there are now three passengers in bus one, and a single passenger entered bus two:
Note that it’s essential that you don’t specify variables that are specific to an object in the class itself. Instead, define these variables within the constructor or in one of the functions using the self-keyword. Otherwise, all instances of that class will share the same variable which might not be what you wanted to achieve.
Import Classes to Build More Complex Programs
So far, I've always used a single file for all the code in these examples. In Python, this is not a problem. However, it’s a good idea to logically distribute large programs over multiple files and load them in as required. One file then contains the main entry point for the program, similar to the index page of a website.
I recommend using individual files for each class in your program. Then create a new file for the main entry point of your application. Let’s suppose that you created three files for three classes named bus.py, car.py, and stop.py. Then, you generated a new file for the main entry point called main.py. The main.py file then looks like this:
from bus import Bus from car import Car from stop import BusStop # Create two bus objects b1 = Bus() b2 = Bus(15, 100) # Create a bus stop stop1 = BusStop() # Create two cars c1 = Car() c2 = Car(max_speed=200) # Let some people enter the busses b1.enter("Peter") b1.enter("Olivia") b1.enter("Frank") b2.enter("Hank") print(b1) print(b2) # Print the top speed of the cars print(c1.max_speed) print(c2.max_speed)
Note how the import statements first specify the filename (without the .py extension) and then tell Python which class to import from that file. In this example, each file contains a single class. Once imported, you can use your custom classes in the main file just like before.
Harnessing Python for Your Projects
Classes help to organize your code by bundling variables and functions in logical units. Typically, a class represents a single entity in your program. You can create new classes in Python by using the class keyword followed by its name. It’s important to remember that variables within the class are shared among all objects of that class. The __init__function is a special function that initializes new objects of a class. Python calls this function automatically when you create an instance of a class.
The first parameter of a function in a class always represents the current object that the method was called for. The programmer, however, doesn’t explicitly supply this parameter. Python does this automatically when you call a function of an object. When writing complex programs, it’s advisable to put classes in separate files. Doing so helps to keep the code clean and easier to maintain.
With these six blogs done, we’ll now turn to more detailed how-to’s and projects that you can follow along with to create your own projects, too!
Recommended Reading
- Intro to Python Programming (Part 1) - Getting Started
- Intro to Python Programming (Part 2) - Python Interpreters
- Intro to Python Programming (Part 3) - Python Lists
- Intro to Python Programming (Part 4) - Call Functions and If-Statements
- Intro to Python for Makers (Part 5) - Custom Functions
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum