Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Class Concepts: Object-Oriented Programming in Python (Summary)

Object-oriented programming means that you’re structuring data and operations on that data together. In Python, you accomplish this by building classes with the class keyword. Attributes are the data values, and methods are the function-like operations that you can perform on classes. In this course, you got a taste of writing code using class and its associated attributes and methods.

In this video course, you’ve learned about:

  • The advantages of object-oriented programming
  • Classes, including how to write them
  • Attributes and methods
  • The descriptor protocol

Now that you know how to write and use classes, you might wonder what else you can do with them. This course is part of a three-part series. Part two covers how to write reusable hierarchies of classes using inheritance, while part three dives deeper into the philosophy behind writing good object-oriented code.

If you’re looking to continue your learning journey, then Real Python’s Object-Oriented Programming (OOP) With Python learning path is for you. Additionally, you can check out the following resources:


Sample Code (.zip)

5.2 KB

Course Slides (.pdf)

1013.9 KB

00:00 In the previous lesson, I showed you all of the things you’ve learned so far in one coding example. This lesson wraps up part one of the course and summarizes what you’ve learned.

00:11 A structure that contains data and operations in Python is defined using the class keyword. And once you have a class, you instantiate it to create an instance of the class called an object.

00:23 Each object has its own attributes and a reference to each method defined in the class. The first method you learned about was the special one known as .__init__().

00:33 This method is called after the object is created and is used to initialize its contents. For most classes, you’ll override the .__init__() method for your own purposes.

00:44 Like all methods, the first argument to .__init__() is self, which when the method is called contains a reference to the newly constructed object.

00:53 You can assign attributes to the object using dot notation. When you do this in .__init__() or any other method, you access the object instance through the self argument. For example, inside Car’s .__init__() method, using self.speed = 3 assigns the value 3 to the attribute named .speed on the instance object.

01:18 An instance object has its own copy of the attributes. When you’re using the object from the outside, you use dot notation on the object to get at its attributes. Within an object’s method, you do the same thing with the object reference called self passed into each method. Attributes can also be at the class level.

01:38 These kinds of attributes are readable by all objects of that class. When you change a class attribute, all objects see the new value. Methods are a special kind of function associated with a class and its objects.

01:53 Instance methods are at the object level and require at least one argument named self, which is the reference of the calling object. Class methods are at the class level.

02:04 They have no knowledge of a specific object. You declare a method as a class method by wrapping it in the @classmethod decorator, and similar to the instance method, they also take at least one argument. In this case, it’s a reference to the class. Class methods are frequently used for factories, an alternative way of creating object instances.

02:26 The third type of method is a static method. These aren’t used very frequently in Python, and they require neither a class nor an object reference. To declare a static method, you wrap it in the @staticmethod decorator.

02:41 The descriptor protocol defines an interface that Python uses to create attribute-like behavior using methods. This gives you fine-grain control over how that thing that looks like an attribute actually behaves under the covers.

02:56 You turn a method into a property by wrapping it with the @property decorator. From the outside, it can be read like an attribute—i.e., without parentheses.

03:06 The user doesn’t need to be aware that this triggers an underlying method

03:11 Associated with the property is the @.setter decorator. This allows you to create a method that is called when you attempt to set the value of a property. Together, the property and setters are like getter and setters in other programming languages, except they hide away the corresponding methods, allowing the user to simply use the property like an attribute.

03:32 The descriptor protocol actually goes even deeper than this, but that will be covered in part two of the course. Speaking of part two, here’s a quick version of what you can look forward to. So far, you’ve been using the attributes and methods on a class, but classes have other features as well.

03:49 You can declare a class using another class in its definition. This is called inheritance and is a way of reusing the functionality of another class while augmenting it and not having to rewrite the code.

04:01 Inheritance can be multilevel: a class can inherit from a class, which inherits from a class, and so on. It can also inherit from multiple classes at the same level.

04:14 All together, these mechanisms provide a good way of writing reusable code. It also allows you to define hierarchical data structures that better map your data to how things appear in the real world.

04:28 That’s it for part one. I hope you found it informative. See you in part two.

Avatar image for mikehillsnc

mikehillsnc on Sept. 8, 2023

I thought I knew all this basic stuff. However i learned

  • about @property

  • use of dict to define new objects with **kwargs

  • why repl works

Cant wait for parts 2 and 3

thank you

Avatar image for Christopher Trudeau

Christopher Trudeau RP Team on Sept. 8, 2023

Glad you found it useful Mike!

Thanks! Any ETA on part 2 and 3? :)

Avatar image for Christopher Trudeau

Christopher Trudeau RP Team on Sept. 10, 2023

Part 2 should be up in the next couple of days. Part 3 will follow a few weeks after that.

Avatar image for alnah

alnah on Oct. 2, 2023

Thank you for your course! I loved it. I was struggling to understand the descriptor protocol and the factory, but now, it’s super clear!

Avatar image for Ash D

Ash D on Dec. 9, 2023

Quite a few “wow” things for me in this course - I liked the cleverness of the descriptor protocol and can immediately see where I can use it to improve some code I’ve been working on lately. Also I didn’t know about class attributes or methods. I don’t fully see the real-world practical case for class attributes or methods, so I’m curious to know what those would be.

Avatar image for Christopher Trudeau

Christopher Trudeau RP Team on Dec. 9, 2023

Hi Ash,

Class attributes and methods don’t have access to the instance values of an object, and so get used in cases where those instance values aren’t important.

Class attributes and methods get shared across all objects, so sometimes they’re used when all instances need to share a single value. As you only get one class attribute across all objects, this can save memory as well.

My most common use of classmethods is the factory pattern. There are cases where you want to construct an object and not directly use the __init__. A factory constructor is a classmethod that instantiates and returns an instance. You might want to do this if __init__ has a lot of arguments, and you want to provide a couple shortcuts that take fewer arguments. You might also do this if creating the object is supposed to have a side effect. One use of this is a singleton pattern: where the goal is to only ever have a single copy of an object. You call the factory classmethod, which checks if an object has been created before. If it has, it returns that object. If it hasn’t it creates it.

A similar example is pools. A pool limits the number of instances of an object. For example, the number of connections to a database, or the number of threads being run. You use the factory to say “get me another connection”, and the classmethod keeps a count as to how many connections are active, and then returns an existing connection or spawns a new one.

Avatar image for Ash D

Ash D on Dec. 11, 2023

Awesome, thanks for the examples, that helped a lot.

Become a Member to join the conversation.