Object-Oriented Programming
Object-oriented programming (OOP) is a programming paradigm that organizes code around objects. Python provides powerful OOP features that make it easier to build reusable, maintainable, and extensible applications.Topics Covered
In this module, you’ll learn:- OOP Refresher
- Class Members vs Instance Members
- Class Methods
- Static Methods
- Magic (Dunder) Methods
- Abstract Base Classes (ABC)
- Multiple Inheritance
- Method Resolution Order (MRO)
- Best Practices
Try Yourself: 💻 VS Code | 🚀 Colab | 📥 DownloadBy the end of this module, you’ll understand how Python objects work internally, customize object behavior, design reusable class hierarchies, and apply advanced OOP concepts effectively.
Verify Solutions: 💻 VS Code | 🚀 Colab | 📥 Download
OOP Refresher
Before exploring advanced concepts, let’s quickly revisit the fundamentals of object-oriented programming.What is OOP?
Object-Oriented Programming (OOP) is a programming paradigm that organizes code around objects. An object combines:- Attributes (data)
- Methods (behavior)
Class and Object
A class is a blueprint for creating objects. An object is an instance of a class.Show Output
Show Output
The Four Pillars of OOP
Python supports four fundamental principles of OOP.
In this module, we’ll build upon these fundamentals and explore advanced OOP concepts.
Everything in Python is an Object
Python follows an object-oriented design where everything is an object—numbers, strings, lists, dictionaries, functions, modules, and even classes. Every object has:- Identity (
id()) - Type (
type()) - State (data)
- Behavior (methods)
Classes are Objects Too
A common misconception is that only instances are objects. In reality, classes themselves are also objects.What Happens When Python Creates a Class?
When Python executes a class definition, it performs these steps internally:- Reads the
classstatement. - Creates a temporary namespace (dictionary).
- Executes every statement inside the class body.
- Collects all attributes and methods into the namespace.
- Calls
type(class_name, bases, namespace). typecreates the new class object.- Assigns the class object to the class name.
bases argument to type().
Creating a Class Dynamically Using type()
Normally, we define classes statically using the class keyword. However, because classes are objects created by type, you can use the type() function as a constructor to create a class dynamically at runtime.
The signature of type() for class creation is:
Example: Static vs. Dynamic Class Creation
Let’s compare the standard static way with the dynamictype() method:
1. The Static Way (Standard):
type):
Show Output
Show Output
type class. When you define a class, Python is actually creating a new custom type.
Class Members vs Instance Members
A class can contain both instance members and class members.Instance Members
Instance members belong to individual objects. Each object maintains its own copy.Show Output
Show Output
Show Output
Show Output
Class Members
Class members are shared by all objects of a class.Show Output
Show Output
Show Output
Show Output
When Should You Use Class Members?
Use class members when a value is shared by every object. Examples include:- Company name
- College name
- Tax rate
- Currency
- Number of objects created
Exercise 1
Create anEmployee class with an instance member name and a class member company.
Sample Input
Solution
Solution
Exercise 2
Create two students and demonstrate that changing an instance member affects only one object. Sample InputSolution
Solution
Properties
Properties provide controlled access to attributes while allowing them to be accessed like normal variables. Instead of callingget_name() and set_name(), properties let you write:
@property decorator.
Read-only Properties
A property that only defines a getter can be read but not modified.Write-only Properties
Although Python does not have true write-only variables, a property can emulate one.Class Methods
A class method operates on the class itself rather than individual objects. A class method is declared using the@classmethod decorator.
Its first parameter is cls, which refers to the class.
Show Output
Show Output
- Access or modify class members.
- Create alternative constructors.
- Perform operations related to the class.
Alternative Constructor
Show Output
Show Output
Exercise 1
Create a class method that displays the company name. Sample InputSolution
Solution
Exercise 2
Create an alternative constructor that converts a name to title case. Sample InputSolution
Solution
Static Methods
A static method belongs to the class but does not access either the class (cls) or the object (self).
Static methods are declared using the @staticmethod decorator.
They are commonly used for utility functions related to the class.
Show Output
Show Output
Show Output
Show Output
When Should You Use Static Methods?
Use a static method when:- The function is related to the class.
- It does not use
self. - It does not use
cls.
Exercise 1
Create a static method that checks whether a number is even. Sample InputSolution
Solution
Exercise 2
Create a static method that converts Celsius to Fahrenheit. Sample InputSolution
Solution
Magic (Dunder) Methods
Magic methods, also known as dunder methods (double underscore methods), are special methods that allow you to customize the behavior of Python objects. They are automatically invoked by Python in response to certain operations such as printing an object, comparing objects, or using operators. Some commonly used magic methods are:The __str__() Method
By default, printing an object displays its memory location.
Show Output
Show Output
__str__() method provides a readable string representation.
Show Output
Show Output
Exercise 1
Implement__str__() for a Book class.
Sample Input
Solution
Solution
Exercise 2
Implement__str__() for an Employee class.
Sample Input
Solution
Solution
The __repr__() Method
The __repr__() method returns an official string representation of an object.
It is mainly intended for developers and debugging.
Show Output
Show Output
Exercise 1
Implement__repr__() for a Product class.
Sample Input
Solution
Solution
Exercise 2
Implement__repr__() for a Course class.
Sample Input
Solution
Solution
Operator Overloading
Magic methods can also customize the behavior of Python operators.The __len__() Method
The len() function internally calls __len__().
Show Output
Show Output
The __eq__() Method
The == operator internally calls __eq__().
Show Output
Show Output
The __add__() Method
The + operator internally calls __add__().
Show Output
Show Output
Exercise 1
Implement__len__() for a Library class that returns the number of books.
Sample Input
Solution
Solution
Exercise 2
Implement__add__() for a Wallet class to combine balances.
Sample Input
Solution
Solution
Abstract Base Classes (ABC)
An Abstract Base Class (ABC) defines a common interface that derived classes must implement. Python provides theabc module to create abstract classes.
Why Use ABC?
- Enforces a common interface.
- Prevents incomplete implementations.
- Encourages consistent class design.
Example
Show Output
Show Output
Exercise 1
Create an abstract classVehicle with an abstract method start().
Implement it in a Car class.
Solution
Solution
Exercise 2
Create an abstract classShape with an abstract method area().
Implement it in a Rectangle class.
Solution
Solution
What Happens During Inheritance?
When Python creates a derived class, it performs these steps:- Resolves the parent classes.
- Validates each base class.
- Computes the Method Resolution Order (MRO).
- Creates the child class namespace.
- Calls
type()to create the new class object. - Stores the inheritance hierarchy.
- Uses the MRO whenever attributes or methods are searched.
Multiple Inheritance
Python allows a class to inherit from more than one base class.Show Output
Show Output
Method Resolution Order (MRO)
When multiple parent classes define the same method, Python follows the Method Resolution Order (MRO) to determine which method to invoke.Show Output
Show Output
Show Output
Show Output
Exercise 1
Create a class that inherits from two parent classes and invoke methods from both.Solution
Solution
Exercise 2
Print the MRO of a class that inherits from two parent classes.Solution
Solution
Best Practices
- Prefer instance members for object-specific data.
- Use class members for shared information.
- Use class methods to work with class-level data.
- Use static methods for utility functions.
- Override only the magic methods you actually need.
- Use abstract base classes to define common interfaces.
- Keep inheritance hierarchies simple and easy to understand.
- Avoid deep multiple inheritance unless necessary.
Practice
To reinforce what you’ve learned in this section, practice with the interactive follow-along notebook:Follow-Along Practice
Practice class/instance variables, class/static methods, custom properties, dunder methods, abstract classes, and multiple inheritance.💻 VS Code | 🚀 Colab | 📥 Download
Summary
In this module, you learned advanced object-oriented programming concepts in Python.Key Concepts Covered
- OOP Refresher
- Class Members vs Instance Members
- Class Methods
- Static Methods
- Magic (Dunder) Methods
- Operator Overloading
- Abstract Base Classes (ABC)
- Multiple Inheritance
- Method Resolution Order (MRO)
- Best Practices