OOP Basics
The concept of OOP in Python focuses on creating reusable code. This concept is also known as DRY (Don’t Repeat Yourself).
Class
A class is a blueprint for the object.
Example
class Parrot:
# class attribute (same for all instances of a class)
species = "bird"
# instance attribute (different for every instance of a class)
def __init__(self, name, age):
self.name = name
self.age = age
Object
An object (instance) is an instantiation of a class.
Example:
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)
Access class attributes:
>>> blu.species
'bird'
>>> woo.species
'bird'
Access instance attributes:
>>> print(f"{blu.name} is {blu.age} years old.")
Blu is 10 years old.
>>> print(f"{woo.name} is {woo.age} years old.")
Woo is 15 years old.
Methods
- Functions defined inside the body of a class
- Define the behaviors of an object
Example
class Parrot:
# class attribute
species = "bird"
# instance attribute
def __init__(self, name, age):
self.name = name
self.age = age
def sing(self, song):
print(f"{self.name} is singing {song}.")
def dance(self):
print(f"{self.name} is dancing.")
>>> blu = Parrot("Blu", 10)
>>> blu.sing("'Happy'")
Blu is singing 'Happy'.
Inheritance
Inheritance enables us to define a class that takes all the functionality from a parent class and allows us to add more.
class SuperClass:
def __init__(self):
pass
def super_method(self):
pass
class SubClass(SuperClass):
def __init__(self):
super().__init__()
pass
def super_method(self):
"""Override method of SuperClass"""
pass
def sub_method(self):
"""Method that only belongs to SubClass"""
pass
Example
# parent class
class Bird:
def __init__(self):
print("Bird is ready")
def who_is_this(self):
print("Bird")
def swim(self):
print("Swim faster")
# child class
class Penguin(Bird):
def __init__(self):
# call super() function
# run the __init__() method of the parent class inside the child class.
super().__init__()
print("Penguin is ready")
# overrides method
def who_is_this(self):
print("Penguin")
def run(self):
print("Run faster")
>>> peggy = Penguin()
Bird is ready
Penguin is ready
>>> peggy.who_is_this()
Penguin
>>> peggy.run()
Run faster
Encapsulation
Encapsulation: Restrict access to methods and variables to prevent data from direct modification.
In python, private attributes is denoted using underscore(s) as the prefix, i.e., _
or __
. The main difference between them is:
- Prefix
_
is just a naming convention indicating a name is meant for internal use. It is NOT enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only. - Prefix
__
triggers name mangling when used in a class context (i.e., can be not directly accessed) and is enforced by the Python interpreter.
More about underscores see: Underscores in Python.
Example:
class Computer:
def __init__(self):
self._min_price = 800
self.__max_price = 900
def sell(self):
print(f"Price: {self._min_price} ~ {self.__max_price}")
def set_max_price(self, max_price):
self.__max_price = max_price
>>> computer.sell()
Price: 800 ~ 900
Variable with __
prefix can not be directly accessed or modified:
>>> computer.__max_price
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-20-2eb906d81ddf> in <module>()
----> 1 computer.__max_price
AttributeError: 'Computer' object has no attribute '__max_price'
>>> computer.__max_price = 1000
>>> computer.sell()
Price: 800 ~ 900
We have to use setters and getters:
>>> computer.get_max_price()
900
>>> computer.set_max_price(1000)
computer.sell()
In contrast, variable with _
can be directly accessed or modified:
>>> computer._min_price
800
>>> computer._min_price = 950
>>> computer._min_price
950
Polymorphism
Polymorphism is an ability (in OOP) to use a common interface for multiple forms (data types).
Example:
class Parrot:
def fly(self):
print("Parrot can fly")
def swim(self):
print("Parrot can't swim")
class Penguin:
def fly(self):
print("Penguin can't fly")
def swim(self):
print("Penguin can swim")
# common interface
def flying_test(bird):
bird.fly()
#instantiate objects
blu = Parrot()
peggy = Penguin()
# passing the object
flying_test(blu)
flying_test(peggy)
Output
Parrot can fly
Penguin can't fly