#15 - Python Classes and Objects

#15 - Python Classes and Objects

By Ifeanyi Omeata


Topics:


1. Python Objects
2. Creating Python Objects with Classes
3. Class Object Attribute
4. Class Object Attribute - Oldest Cats Example
5. Encapsulation
6. Abstraction
7. Inheritance
8. Single Inheritance
9. Multiple Inheritance
10. Multi-level Inheritance
11. Hierarchical inheritance
12. Hybrid Inheritance
13. Isinstance Method
14. Polymorphism
15. Polymorphism - Cat Example
16. Use Parent Constructor Init function
17. Use Parent Constructor Init with super()
18. Use dir() to view Attributes and Methods of Object
19. Dunder Methods
20. Dunder Methods - SuperList Example
21. IsSubclass Method
22. MRO - Method Resolution Order
23. OOP Example I


1. Python Objects


>>Return to Menu





#OOP
class BigObject:
    pass

obj1 = BigObject()
obj2 = BigObject()
obj3 = BigObject()

#OOP
print(type(None))
print(type(True))
print(type(5))
print(type(5.5))
print(type('hi'))
print(type([]))
print(type(()))
print(type({}))
print(type(obj1))

image.png


2. Creating Python Objects with Classes


>>Return to Menu


class PlayerCharacter:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def run(self):
        return 'This is a "run" method.'

player1 = PlayerCharacter('Bob',23)
player2 = PlayerCharacter('Mary',30)  

print(player1.name)
print(player2.age)
player2.weight = "80kg"
print(player2.weight)

print(player1.run())

image.png


3. Class Object Attribute


>>Return to Menu

class PlayerCharacter:
    position = "defender"
    def __init__(self,name="Sally",age=50):
        if self.position == "striker":
            self.name = name
            self.age = age            
        else:
            self.name = f"Your name is {name}"
            self.age = f"Your age is {age}"   

    def greet(self):
        return f'Hello, {self.name}!'

player1 = PlayerCharacter('Bob',23)
player2 = PlayerCharacter('Mary',30)  
player3 = PlayerCharacter()  

print(player1.name)
print(player2.age)
print(player3.name,player3.age)
print(player1.greet())

image.png


4. Class Object Attribute - Oldest Cats Example


>>Return to Menu

#Given the below class:
class Cat:
    species = 'mammal'
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 1 Instantiate the Cat object with 3 cats
cat1 = Cat('Rubby',12)
cat2 = Cat('Carl',3)
cat3 = Cat('Jody',4)

# 2 Create a function that finds the oldest cat
def get_oldest_cat(*args):
  return max(args)

# 3 Print out: "The oldest cat is x years old.". x will be the oldest cat age by using the function in #2
print(f"The oldest cat is {get_oldest_cat(cat1.age, cat2.age, cat3.age)} years old.")

image.png


5. Encapsulation


>>Return to Menu

class PersonCharacter:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    def speak(self):
        return (f'My name is {self._name}, and I am {self._age} years old.')

person = PersonCharacter('James',34)
print(person.speak())

image.png


6. Abstraction


>>Return to Menu
An abstract class can be considered as a blueprint for other classes. It allows you to create a set of methods that must be created within any child classes built from the abstract class. A class which contains one or more abstract methods is called an abstract class.
When we want to provide a common interface for different implementations of a component, we use an abstract class.
A method becomes abstract when decorated with the keyword @abstractmethod.

# Python program showing
# abstract base class work

from abc import ABC, abstractmethod

class Polygon(ABC):
    @abstractmethod
    def sides(self):
        pass

class Triangle(Polygon):
    def sides(self):
        print("I have 3 sides")

class Pentagon(Polygon):
    def sides(self):
        print("I have 5 sides")

class Hexagon(Polygon):
    def noofsides(self):
        print("I have 6 sides")

class Quadrilateral(Polygon):

    # overriding abstract method
    def noofsides(self):
        print("I have 4 sides")


R = Triangle()
R.noofsides()

K = Quadrilateral()
K.noofsides()

R = Pentagon()
R.noofsides()

K = Hexagon()
K.noofsides()


7. Inheritance


>>Return to Menu

Different Forms of Inheritance in Object Oriented Programming

  • Single Inheritance
  • Multiple Inheritance
  • Multi-level Inheritance
  • Hierarchical Inheritance
  • Hybrid Inheritance
class Student():
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

class Course(Student):
    def details(self):
        return (f'Name: {self.name}, Age: {self.age}, Sex: {self.sex}')        

student1 = Course('Adams',42,'Male')
print(student1.details())

image.png

Another Example:

class User():
    def start(self, name, age):
        print('logged in')
        return {'name' : name, 'age': age}

class Level(User):
    def __init__(self, lvl, power):
        self.lvl = lvl
        self.power = power

    def welcome(self, time):
        self.time = time
        return f'Welcome to {self.lvl}. Its {time}.'  

level1 = Level('level 1', '50hz') 

print(level1.lvl)
print(level1.power)
print(level1.start('John', 34))
print(level1.welcome('morning'))

image.png


8. Single Inheritance


>>Return to Menu

class Parent:
  def f1(self):
    print("Function of parent class.")

class Child(Parent):
  def f2(self):
    print("Function of child class.")

object1 = Child()
object1.f1()
object1.f2()


9. Multiple Inheritance


>>Return to Menu

class Parent_1:
  def f1(self):
    print("Function of parent_1 class.")

class Parent_2:
  def f2(self):
    print("Function of parent_2 class.")

class Parent_3:
  def f3(self):
    print("function of parent_3 class.")

class Child(Parent_1, Parent_2, Parent_3):
  def f4(self):
    print("Function of child class.")

object_1 = Child()
object_1.f1()
object_1.f2()
object_1.f3()
object_1.f4()


10. Multi-level Inheritance


>>Return to Menu

class Parent:
  def f1(self):
    print("Function of parent class.")

class Child_1(Parent):
  def f2(self):
    print("Function of child_1 class.")

class Child_2(Child_1):
  def f3(self):
    print("Function of child_2 class.")

obj_1 = Child_1()
obj_2 = Child_2()

obj_1.f1()
obj_1.f2()

print("\n")
obj_2.f1()
obj_2.f2()
obj_2.f3()


11. Hierarchical inheritance


>>Return to Menu

class Parent:
deff1(self):
print("Function of parent class.")

class Child_1(Parent):
deff2(self):
print("Function of child_1 class.")

class Child_2(Parent):
deff3(self):
print("Function of child_2 class.")

obj_1 = Child_1()
obj_2 = Child_2()

obj_1.f1()
obj_1.f2()

print('\n')
obj_2.f1()
obj_2.f3()


12. Hybrid Inheritance


>>Return to Menu

class Parent:
  def f1(self):
    print("Function of parent class.")

class Child_1(Parent):
  def f2(self):
    print("Function of child_1 class.")

class Child_2(Parent):
  def f3(self):
    print("Function of child_2 class.")

class Child_3(Child_1, Child_2):
  def f4(self):
    print("Function of child_3 class.")

obj = Child_3()
obj.f1()
obj.f2()
obj.f3()
obj.f4()


13. Isinstance Method


>>Return to Menu

class User():
    def start(self, name, age):
        print('logged in')
        return {'name' : name, 'age': age}

class Level(User):
    def __init__(self, lvl, power):
        self.lvl = lvl
        self.power = power

    def welcome(self, time):
        self.time = time
        return f'Welcome to {self.lvl}. Its {time}.'  

class Action():
    pass

level1 = Level('level 1', '50hz') 

print(level1.start('John', 34))
print(level1.lvl)
print(level1.power)
print(level1.welcome('morning'))

print(isinstance(level1, object))
print(isinstance(level1, User))
print(isinstance(level1, Level))
print(isinstance(level1, Action))

image.png


14. Polymorphism


>>Return to Menu

class Student():
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def details(self):
        return {'name': self.name, 'age': self.age, 'sex': self.sex}    

class Course(Student):
    def __init__(self,course,score,pass_or_fail):
        self.course = course
        self.score = score 
        self.pass_or_fail = pass_or_fail

    def details(self):
        return (f'Course: {self.course}, Score: {self.score}, Result: {self.pass_or_fail}')        

class Hostel(Student):
    pass

student1 = Course('Maths',82,'Pass')
print(student1.details())
student2 = Student('Henry',34,'Male')
print(student2.details())

image.png


15. Polymorphism - Cat Example


>>Return to Menu

class Pets():
    animals = []

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

    def walk(self):
        for animal in self.animals:
            print(animal.walk())

class Cat():
    is_lazy = True

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

    def walk(self):
        return f'{self.name} is just walking around'

class Simon(Cat):
    def sing(self, sounds):
        return f'{sounds}'

class Sally(Cat):
    def sing(self, sounds):
        return f'{sounds}'

#1 Add another Cat
class Molly(Cat):
    def sing(self, sounds):
        return f'{sounds}'

#2 Create a list of all of the pets (create 3 cat instances from the above)
my_cats = [(cat_simon := Simon('Simon', 6)), (cat_sally := Sally('Sally', 3)), (cat_molly := Molly('Molly', 12))]

#3 Instantiate the Pet class with all your cats use variable my_pets
my_pets = Pets(my_cats)

#4 Output all of the cats walking using the my_pets instance
my_pets.walk()

#5 (Optionally) make the cats sing your tune... 😸
print(cat_simon.sing('lala'))
print(cat_molly.sing('meow'))

image.png


16. Use Parent Constructor Init function


>>Return to Menu

class Student():
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def details(self):
        return {'name': self.name, 'age': self.age, 'sex': self.sex}    

class Course(Student):
    def __init__(self,name,age,sex,course,score,is_pass):
        Student.__init__(self,name,age,sex)
        self.course = course
        self.score = score 
        self.is_pass = is_pass

    def details(self):
        return {'name': self.name, 
                'age': self.age,
                'sex': self.sex,
                'course': self.course,
                'score': self.score,
                'is_pass': self.is_pass,}      

student1 = Course('Andrew',34,'Male','Maths',82,True)
print(student1.details())
print(Student.details(student1))

image.png


17. Use Parent Constructor Init with super()


>>Return to Menu

class Student():
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def details(self):
        return {'name': self.name, 'age': self.age, 'sex': self.sex}    

class Course(Student):
    def __init__(self,name,age,sex,course,score,is_pass):
        super().__init__(name,age,sex)
        self.course = course
        self.score = score 
        self.is_pass = is_pass

    def details(self):
        return {'name': self.name, 
                'age': self.age,
                'sex': self.sex,
                'course': self.course,
                'score': self.score,
                'is_pass': self.is_pass,}      

student1 = Course('Andrew',34,'Male','Maths',82,True)
print(student1.details())
print(Student.details(student1))

image.png


18. Use dir() to view Attributes and Methods of Object


>>Return to Menu

class Student():
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def details(self):
        return {'name': self.name, 'age': self.age, 'sex': self.sex}    

class Course(Student):
    def __init__(self,name,age,sex,course,score,is_pass):
        super().__init__(name,age,sex)
        self.course = course
        self.score = score 
        self.is_pass = is_pass

    def details(self):
        return {'name': self.name, 
                'age': self.age,
                'sex': self.sex,
                'course': self.course,
                'score': self.score,
                'is_pass': self.is_pass,}      

student1 = Course('Andrew',34,'Male','Maths',82,True)
print(dir(student1))

image.png


19. Dunder Methods


>>Return to Menu

class Toy():
    def __init__(self, color, age):
        self.color = color
        self.age = age
        self.my_dict = {
            'name':'Yoyo',
            'has_pets': False,
        }

    def __str__(self):
        return f"{self.color}"

    def __len__(self):
        return 5

    def __del__(self):
        return "deleted"

    def __call__(self):
        return('yes??')

    def __getitem__(self,i):
        return self.my_dict[i]

Bob_the_builder = Toy('red', 2)
print(Bob_the_builder.__str__())
print(str(Bob_the_builder))

print(len(Bob_the_builder))
print(Bob_the_builder())
print(Bob_the_builder['name'])

image.png


20. Dunder Methods - SuperList Example


>>Return to Menu

class SuperList(list):
    def __len__(self):
        return 1000

super_list1 = SuperList();

print(len(super_list1))

super_list1.append(5)
print(super_list1[0])

image.png


21. Issubclass Method


>>Return to Menu

class SuperList(list):
    def __len__(self):
        return 1000

super_list1 = SuperList();

print(len(super_list1))

super_list1.append(5)
print(super_list1[0])

print(issubclass(SuperList, list))
print(issubclass(list, object))

image.png


22. MRO - Method Resolution Order


>>Return to Menu

#MRO - Method Resolution Order
class A:
    num = 10

class B(A):
    pass

class C(A):
    num = 1

class D(B, C):
    pass

print(D.mro())
print(D.__mro__)

image.png


23. OOP Example I


>>Return to Menu

class Employee():
    raise_amt = 1.04

    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.pay = pay
        self.email = f'{first.lower()}.{last.lower()}@gmail.com'

    def fullname(self):
        return '{} {}'.format(self.first, self.last)

    def apply_raise(self):
        self.pay = int(self.pay * self.raise_amt)     

class Developer(Employee):
    raise_amt = 1.10  

    def __init__(self, first, last, pay, prog_lang):
        super().__init__(first, last, pay)  
        self.prog_lang = prog_lang    

class Manager(Employee):
    def __init__(self, first, last, pay, employees=None):
        super().__init__(first, last, pay)  
        self.employees = [] if employees is None else employees

    def add_employee(self, employee):
        if employee not in self.employees:
            self.employees.append(employee)

    def remove_employee(self, employee):
        if employee in self.employees:
            self.employees.remove(employee)

    def print_employees(self):
        for employee in self.employees:
            print('--->', employee.fullname())                     

dev1 = Developer('Mike','Smith', 50000, 'Python')
dev2 = Developer('Mary','Poppings', 60000, 'Java')

manager1 = Manager('James','Thomas',90000)
manager1.add_employee(dev1)
manager1.add_employee(dev2)
manager1.print_employees()
print(manager1.fullname())

print(isinstance(manager1, Developer))
print(issubclass(Developer, Employee))

#End


Hope you enjoyed this! :) Follow me for more contents...


Get in Touch:
ifeanyiomeata.com

Youtube: youtube.com/c/IfeanyiOmeata
Linkedin: linkedin.com/in/omeatai
Twitter: twitter.com/iomeata
Github: github.com/omeatai
Stackoverflow: stackoverflow.com/users/2689166/omeatai
Hashnode: hashnode.com/@omeatai
Medium: medium.com/@omeatai
© 2022