OOP in Python: Why is object-oriented programming so important?

MP 36: What is OOP, and why does everybody ask about it?

Note: This is the first post in a series about OOP in Python. The next post discusses the role of self, and why it’s important in object-oriented code.


When people start to learn Python, object-oriented programming (OOP) is often one of the first topics they struggle to grasp. This is not surprising; OOP encompasses so many ideas, it’s hard to make sense of it all when you’re new to programming. It’s one of those topics where it can be easy to learn the basics, but then at some point you realize just how much else there is to learn. And if you skim the headlines of technical news sites, OOP can sound like the best thing that ever happened to programming on some days, and the worst thing that ever happened on other days. How do you make sense of that?!

In this series we’ll take a closer look at a number of topics related to object-oriented programming in Python. The goal is to understand what’s happening behind the scenes in object-oriented code, and why code is often structured this way. We’ll look at some patterns to use in your own code, and some patterns to watch out for as well.

What is “object-oriented programming”?

My father was a programmer in the 1970s and 80s, so I grew up hearing phrases like “object-oriented programming” from a young age. It always sounded mysterious and complex, and I wondered if I’d ever use it or understand it. OOP wasn’t covered in the first few programming classes I took, which only built the mystery up further. When I finally learned the basics, I remember thinking “That’s it?!”

OOP was first described to me as “a way of storing information and actions in one place.” That description has served me well in making sense of various takes on OOP, over multiple decades and a number of different programming languages. Most OOP critics I’ve read and listened to who object to a simple description like this are usually trying to discuss subtle aspects of how we store information and actions together. Many critics have moved so far beyond basic use cases that they’ve lost sight of how useful OOP is for solving a large class of problems people care about.

What does it mean to “store information and actions in one place”? Here’s a tiny example:

class Robot:

    def __init__(self, name):
        self.name = name

    def say_hello(self):
        print(f"Hello, I'm {self.name}!")

There’s one piece of information here, the robot’s name. There’s also one action; it can say hello. Both the information associated with a robot, and its functionality are contained in the class Robot.

Why is OOP so important?

OOP caught on in part because it makes it easier to do the work that many people care about as programmers. Imagine a Robot class with more information and actions defined. Try to get a sense of what the following code might do:

my_robot = Robot("William")

my_robot.say_hello()
my_robot.walk()

my_robot.speed += 10
my_robot.jump()
my_robot.spin()
my_robot.stop()

my_robot.say_hello()

I don’t really have to describe what all of this does, because it reads quite clearly as it’s written. Once you’ve defined a class, using objects from the class turns out to be a really powerful way to get work done.

Also, take a look at this single line of code:

my_robot_army = [Robot() for _ in range(1_000)]

With no additional code, we can build an army of 1,000 virtual robots in one line of code.1 There are ways to do this without OOP, but using OOP is still one of the most practical ways to structure code so you can solve the problems you care about reasonably efficiently and effectively.

But I never write classes…

Even if you rarely write classes, a solid understanding of OOP will still go a long way towards helping you become a better Python programmer. Everything in Python is an object, so even if you don’t write your own classes you’re still using OOP. And that’s fine; one of the main points of structuring code as a class is so others can just work with objects of the class. The more you understand about OOP, the better you’ll be able to work with the objects that are created from other people’s classes.

Conclusions

OOP is all around us in Python. It’s a huge topic, which means most people come out of their intro and intermediate learning experiences without a full understanding of many aspects of OOP. In this series, we’ll look into a number of aspects of OOP that many people aren’t fully aware of.

In the next post, we’ll start with one of the most often-asked questions about OOP in Python: What exactly is self?


  1. If you are unfamiliar with list comprehensions, see MP #5, Understanding comprehensions. Basically, this code is equivalent to the following loop:

    my_robot_army = []
    
    for _ in range(1_000):
        new_robot = Robot()
        my_robot_army.append(new_robot)

    This makes an empty list, and then starts a loop that runs 1,000 times. On each pass through the loop a new Robot object is created, and appended to the list my_robot_army. The code shown above does all of this in one line.