Understanding Python's Object-Oriented Paradigm
Python follows object-oriented programming principles similar to Java, featuring class creation, member attributes, member methods, constructors, inheritance, and other OOP operations.
If you're unfamiliar with OOP concepts, this guide will help you grasp the fundamentals through practical examples.
Practical Example: Creating a Vehicle Class
Let's create a Vehicle class with brand and year properties, along with methods for starting and stopping the engine.
class Vehicle:
brand = "Unknown"
year = 2000
def start_engine(self):
print("Engine started successfully")
def stop_engine(self):
print("Engine stopped")
if __name__ == '__main__':
v1 = Vehicle()
print(v1.brand)
print(v1.year)
v1.start_engine()
v1.stop_engine()
Output:
Unknown
2000
Engine started successfully
Engine stopped
The Self Parameter
Every method in a class includes the self parameter, which represents the instance of the class rather than the class itself. This is the key difference between class methods and regular functions. By convention, we use 'self' as the parameter name (though it can be renamed, this is strongly discouraged).
def show_identity(self):
print(f"Instance: {self}")
print(f"Class: {self.__class__}")
Output:
Instance: <__main__.Vehicle object at 0x0000018A0B5B3D68>
Class: <class '__main__.Vehicle'>
Constructor Method: init
The init method initializes objects when they are created. Let's modify our Vehicle class to accept initialization parameters:
class Vehicle:
def __init__(self, brand, year):
self.brand = brand
self.year = year
def start_engine(self):
print(f"{self.brand} engine roaring to life")
def stop_engine(self):
print("Engine shut down")
if __name__ == '__main__':
car = Vehicle("Toyota", 2023)
print(f"{car.brand} {car.year}")
car.start_engine()
car.stop_engine()
Output:
Toyota 2023
Toyota engine roaring to life
Engine shut down
Note: Python doesn't support method overloading, so each class can only have one init method. You can impleemnt different initialization logic using optional parameters.
Class Inheritance
Inheritance syntax in Python:
class ChildClass(ParentClass):
Let's create a Car class that inherits from Vehicle:
class Vehicle:
def __init__(self, brand, year):
self.brand = brand
self.year = year
def start_engine(self):
print("Vehicle engine started")
class Car(Vehicle):
def __init__(self, brand, year, model):
super().__init__(brand, year)
self.model = model
def honk_horn(self):
return "Beep beep!"
if __name__ == '__main__':
sedan = Car("Honda", 2022, "Civic")
print(f"{sedan.brand} {sedan.model} {sedan.year}")
sedan.start_engine()
print(sedan.honk_horn())
Output:
Honda Civic 2022
Vehicle engine started
Beep beep!
Multiple Inheritance
Python supports multiple inheritance:
class DerivedClass(Base1, Base2, Base3):
The order of parent classes matters. When methods with the same name exist in multiple parent clases, Python searches from left to right.
Method Overriding
Child classes can override parent class methods to provide specific implementations:
class Car(Vehicle):
def __init__(self, brand, year, model):
super().__init__(brand, year)
self.model = model
def start_engine(self):
print(f"{self.brand} electric motor silently activated")
def honk_horn(self):
return "Beep beep!"
if __name__ == '__main__':
electric_car = Car("Tesla", 2023, "Model 3")
electric_car.start_engine()
Output:
Tesla electric motor silently activated
Private Attributes and Methods
Python uses double underscores to denote private members:
Private attributes: __private_attrPrivate methods: __private_method
class Vehicle:
def __init__(self, brand, year):
self.brand = brand
self.year = year
self.__vin_number = "SECRET123"
def get_private_info(self):
return self.__vin_number
def __internal_method(self):
return "Internal operation"
if __name__ == '__main__':
v = Vehicle("BMW", 2021)
print(v.get_private_info())
# print(v.__vin_number) # This would raise AttributeError
# v.__internal_method() # This would raise AttributeError
Output:
SECRET123
Python Special Methods
| Method | Description |
|---|---|
| __init__ | Constructor, called when creating an object |
| __del__ | Destructor, called when object is destroyed |
| __str__ | String representation for str() |
| __repr__ | String representation for repr() |
| __len__ | Returns length for len() |
| __getitem__ | Access item using index |
| __setitem__ | Assign item using index |
| __call__ | Make object callable |
| __add__ | Behavior for + operator |
| __sub__ | Behvaior for - operator |
| __mul__ | Behavior for * operator |
| __truediv__ | Behavior for / operator |
| __mod__ | Behavior for % operator |
| __pow__ | Behavior for ** operator |
These special methods can be overridden to customize object behavior.