0% found this document useful (0 votes)
13 views59 pages

Day 5.1 - CH10 - Object Oriented Programming

Uploaded by

nguejip47
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
Download as pptx, pdf, or txt
0% found this document useful (0 votes)
13 views59 pages

Day 5.1 - CH10 - Object Oriented Programming

Uploaded by

nguejip47
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1/ 59

1ALG

ALGORITHMS WITH
PYTHON

Chapter 10: Object Oriented programming


Summary
- What is object-oriented
programming.
- Four pillars of OOP.
- Override default behaviors.
- Storing information with
dataclasses.
Object-Oriented Programming
3
What is Object-Oriented Programming
- A way of structing data by grouping related properties and behaviors into individual objects.

- For example, an object that represents Dog :


- A dog has a name
- A dog has an age
- A dog can bark
- A dog can sleep
- ..

4
Concept : A dog

Name
Attributes
Age

Dog
Bark

Actions Sleep

Run

5
Four pillars of OOP

Encapsulation : objects are self-contained

Abstraction : hides the implementations

Polymorphism : can be used in different contexts

Inheritance : objects can be derived from other objects

6
Benefits of OOP

REUSABILITY MODULARITY EXTENSIBILITY MAINTAINABILITY

7
OOP in python

- In python everything is an object !

- Objects are created from templates called classes.

- Classes are defined in class blocks class <ClassName>:


pass

- An object created from a class is called an instance of the class.

8
Objects creations

# class definition
class Dog:
pass

# creation of an instance of Dog


my_dog = Dog()

# you can create multiple instances


other_dog = Dog()

9
Class constructor

First method called on instance creation.

Can be used to define instance attributes.

A default constructor is present for all classes.

10
Class constructor - example
# class definition
class User:
# constructor definition
def __init__(self, name: str):
# self represents the current instance
self.name = name

# creation of two different instances


user_a = User("Bob")
user_b = User("Alice")

# print the name of both users


# we get the name by doing <object>.<attribute>
print(user_a.name, user_b.name)
11
Instance attributes vs class attributes

Instance • belongs to the instance.


• instances can have different values.
attributes
Class • belongs to the class.
• all instances share the same value.
attributes
12
Instance attributes vs Class attributes

class User:
ROLE = "viewer" # class attribute

def __init__(self, name: str):


self.name = name # instance attribute

bob = User("Bob")
alice = User("Alice")

print(bob.name, bob.ROLE)
>>> Bob viewer
print(alice.name, alice.ROLE)
>>> Alice viewer

13
Instance methods

- Functions defined inside a class and called from an instance.

- We have already used methods before.

- Syntax is <instance>.<method>(self, param1, …)

14
Methods - example
class User:
def __init__(self, name: str):
self.name = name

def say_hi(self):
print(f"Hi, my name is {self.name}.")

bob = User("Bob")
bob.say_hi()

>>> Hi, my name is Bob.


15
Inheritance
16
Inheritance explained

- A class can extends another class.

- Newly formed class is a child and takes all the attributes and methods of its parent.

- Childs can override attributes or methods of their parents.

17
Inheritance - schema

18
Inheritance – example
class Animal:
def eat(self):
print("I am eating.")

class Dog(Animal):
def bark(self):
print("I am barking.")

my_dog = Dog()

my_dog.eat() # Dog inherits eat from Animal


my_dog.bark() # Dog can bark

19
Overriding methods
class Parent:
def example_method(self):
print("Method of the Parent class.")

class Child(Parent):
# method has the same name as the one from the parent
def example_method(self):
print("Method of the Child class.")

obj = Child()
obj.example_method()

>>> Method of the Child class.

20
Calling parents : the super() built-in

Returns the parent class

Direct access to the parent's methods

Don't need to pass the "self" reference


21
Calling parent methods
class Parent:
def example_method(self):
print("Method of the Parent class.")

class Child(Parent):
def example_method(self):
# super() is used to call the method from the parent
super().example_method()
print("Method of the Child class.")

obj = Child()
obj.example_method()

>>> Method of the Parent class.


>>> Method of the Child class.
22
Calling parent constructor
class Animal:
def __init__(self, sound: str):
self.sound = sound

def make_sound(self):
print(self.sound)

class Dog(Animal):
def __init__(self, name: str, sound: str = "Woof"):
super().__init__(sound) # call the parent constructor
self.name = name

my_dog = Dog("Bob")
my_dog.make_sound()
23
Checking if an instance belongs to a class

- Don't use type() to check if an object belongs to a class.

- Use the isinstance() built-in function.

status = isinstance(obj, class)

24
Using isinstance() - example
class Base: pass
class A(Base): pass
class B(Base): pass
class Other: pass

objects = [Base(), A(), B(), Other()]


for obj in objects:
print(f"{type(obj)} {isinstance(obj, Base)=}")

<class '__main__.Base'> isinstance(obj, Base)=True


<class '__main__.A'> isinstance(obj, Base)=True
<class '__main__.B'> isinstance(obj, Base)=True
<class '__main__.Other'> isinstance(obj, Base)=False

25
Encapsulation

26
Restrict access from outside
the class

Encapsulation Protects sensitive data


explained

Makes the code safer

27
Encapsulation scope

Scope Description Norm


public Accessible from everywhere outside the class name

protected Accessible only from the class and its childs _name

private Accessible only from within the class __name

Note that in Python this is mainly used as an indication and can be bypassed...

28
Encapsulation example
class Item:
def __init__(self, id: int, name: str, quantity: int):
self.__id = id # private
self._name = name # protected
self.quantity = quantity # public

class Phone(Item):
def __init__(self, id: int, name: str, quantity: int):
super().__init__(id, name, quantity)

samsumg = Phone(1, "Samsung Galaxy", 42)

print(samsumg.quantity) # we can access the quantity


print(samsumg._name) # protected is just an indication
print(samsumg.__id) # AttributeError, can't access __id
29
What does python do for encapsulation ?

Public • Nothing

Protected • Nothing, it is just an indication

Private • Attribute / method is renamed

30
Working with private attributes

Accessors

• Can ensure validity of new value before update.


• Can transform the attribute before reading it.
• Called getters and setters.

31
Basic getters / setters
class Item:
def __init__(self, quantity: int):
self.__quantity = quantity

def get_quantity(self) -> int:


return self.__quantity

def set_quantity(self, quantity: int) -> int:


if quantity < 0:
raise ValueError("quantity can't be less than 0")
self.__quantity = quantity

item = Item(3)
item.get_quantity() # returns 3
item.set_quantity(1) # quantity is now 1
32
The @property decorator

Used on methods for getters/setters

Change the behaviors of attributes get/set

Make the code easier to read

33
The @property decorator
class Item:
def __init__(self, quantity: int):
self.__quantity = quantity

@property
def quantity(self) -> int:
return self.__quantity

@quantity.setter
def quantity(self, quantity: int) -> int:
if quantity < 0:
raise ValueError("quantity can't be less than 0")
self.__quantity = quantity

item = Item(3)
item.quantity # returns 3
item.quantity = 1 # quantity is now 1
34
Abstraction
35
Abstraction concepts

• Define blueprints for child classes.

• Provide methods definition but no implementation.

• Abstract classes can't be instantiated.

• Force childs to implement abstract methods.

36
The Abstract Base Class (abc) module

Provide needed resources for abstraction.

Abstracts classes must inherit from the ABC class.

Abstracts methods are decorated with


@abstractmethod.
37
Abstraction example
from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def make_noise(self):
pass

class Dog(Animal):
def make_noise(self):
print("Woof woof")

a = Animal() # TypeError: Can't instantiate abstract class


d = Dog() # Class is created
d.make_noise() # Instance method is called
38
Polymorphism

39
Polymorphism explained

A method or function that can Behaviors can depend on the class Related concept to inheritance.
have different behaviors. or context.

40
Polymorphism behaviors - examples

- With len() : len([0, 1, 2]) # count items


len("obi-wan") # count characters
len({"a": 0, "b": 1}) # count keys

- With an addition : 3 + 2 # math addition


"a" + "b" # str concatenation
[0] + [1] # list merge

41
Polymorphism with OOP example
from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def make_noise(self):
pass

class Dog(Animal):
def make_noise(self):
print("Woof woof")

class Cat(Animal):
def make_noise(self):
print("Meow Meow")
42
Operator overloading
43
Operator overload

- In python everything is an object.

- Operations like additions or subtractions are implemented by specials


methods

- These special methods are called magic methods.

44
Operator override - example
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y

# override the default behaviors for additions


def __add__(self, other) -> "Vector":
return Vector(self.x + other.x, self.y + other.y)

a = Vector(4, 2)
b = Vector(1, 1)
c = a + b # Vector(5, 3)
45
Operator overload - maths

Operator method
+ __add__(self, other)
- __sub__(self, other)
* __mul__(self, other)
/ __truediv__(self, other)
// __floordiv__(self, other)
% __mod__(self, other)
** __pow__(self, other)

46
Operator overload - assignment

Operator method
+= __iadd__(self, other)
-= __isub__(self, other)
*= __imul__(self, other)
/= __itruediv__(self, other)
//= __ifloordiv__(self, other)
%= __imod__(self, other)
**= __ipow__(self, other)

47
Operator overload - comparison

Operator method
< __lt__(self, other)
> __gt__(self, other)
<= __le__(self, other)
>= __ge__(self, other)
== __eq__(self, other)
!= __ne__(self, other)

48
List all magic methods

- All magic methods can be found in the python doc.

- More than 30 magic methods that can be overloaded.

- Can list all methods implemented with the dir() built-in function.

dir( object )

49
Representation override

- When printing an object, its __repr__ method is called.

- This method returns a str representing the object.

- By default, the __repr__ is not very useful.

print(Vector(4, 2)) => "<__main__.Vector object at 0xfffffffff>"

50
Representation override

class Vector:
def __init__(self, x, y):
self.x = x
self.y = y

# override the object representation


def __repr__(self) -> str:
return f"Vector{{{self.x}, {self.y}}}"

v = Vector(4, 2)
print(v) # Vector{4, 2}
51
Dataclasses

52
Dataclasses

A type of class that is only used to store data.

Makes code simpler in some cases.

Many magic methods are already pre-configured.

53
Dataclasses benefits
- Conciseness : automatically generates special methods
- Readability : makes the code more readable
- Default values : you can provide default values in the class declaration
- Immutability : dataclasses are perfects to use as immutable objects
- Equality Comparison : automatically provide __eq__ support
- Hash support : automatically provide __hash__ so they can be used as keys in dict

54
Dataclasses - example

class User: from dataclasses import dataclass


def __init__(self, name: str,
age: int, job: str): @dataclass
self.name = name class User:
self.age = age name: str
self.job = job age: int
job: str
obiwan = User("Obi-Wan", 42, "Jedi")
print(obiwan) obiwan = User("Obi-Wan", 42, "Jedi")
print(obiwan)

<__main__.User object at 0xffffff> User(name='Obi-Wan', age=42, job='Jedi')

55
Dataclasses – frozen example

from dataclasses import dataclass

# frozen dataclass, can't be modified


@dataclass(frozen=True)
class ForceUser:
name: str
age: int
job: str = "Jedi"

obiwan = ForceUser("Obi-Wan", 42, "Jedi Master")


obiwan.name = "Old ben"

dataclasses.FrozenInstanceError: cannot assign to field 'name'


56
Dataclasses - conversion
from dataclasses import dataclass, asdict, astuple

@dataclass
class ForceUser:
name: str
age: int
job: str = "Jedi"

obiwan = ForceUser("Obi-Wan", 42, "Jedi Master")


print(asdict(obiwan)) # convert to dict
print(astuple(obiwan)) # convert to tuple

{'name': 'Obi-Wan', 'age': 42, 'job': 'Jedi Master'}


('Obi-Wan', 42, 'Jedi Master')
57
Conclusion
- In python everything is an object.
- Objects allows you to group behaviors and
values.
- The four pillars of OOP are : abstraction,
inheritance, polymorphism, encapsulation.
- You can change native behaviors using
magic methods.

58
Let’s practice !

59

You might also like