0% found this document useful (0 votes)
2 views36 pages

OOP in Python

The document discusses the Object-Oriented Programming (OOP) paradigm, highlighting its advantages over unstructured/procedural programming, such as data encapsulation, code reusability, and modularity. It explains key concepts like classes, objects, inheritance, encapsulation, abstraction, and polymorphism, along with their definitions and examples. The document also covers the importance of method resolution order and the use of decorators for encapsulation in Python.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views36 pages

OOP in Python

The document discusses the Object-Oriented Programming (OOP) paradigm, highlighting its advantages over unstructured/procedural programming, such as data encapsulation, code reusability, and modularity. It explains key concepts like classes, objects, inheritance, encapsulation, abstraction, and polymorphism, along with their definitions and examples. The document also covers the importance of method resolution order and the use of decorators for encapsulation in Python.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd

OOP Paradigm

(classes, objects and


related concepts)

Advance Python Programming


Instructor: Izza Yaqoob
Problems with unstructured/procedural
programming

o No data encapsulation : Data and functions were separate; any function could modify any data,
leading to unintended side effects and hard-to-trace bugs
o Global state pollution: Heavy reliance on global variables made code unpredictable; changes in one
part of the program could silently break another
o No code reusability: Functions were isolated; copying and pasting code was common, leading to
duplication and maintenance nightmares
o Tight coupling: Functions depended heavily on each other's internal details. Changing one function
broke others unexpectedly
o Poor scalability: As programs grew, the flat structure became unmanageable; spaghetti code with
tangled control flow
Problems with unstructured/procedural
programming

o Low cohesion: Related data and behavior were scattered across different files/modules. A
player_score variable might be declared in main, updated in game_logic, and displayed in render —
three separate places for one concept.
o No access control : Could not restrict which parts of code could modify specific data; everything was
exposed
o Naming collisions: All functions and variables shared a global namespace; name conflicts were
frequent in large programs
o Hard to model real-world entities : A "Customer" was just a bundle of variables, not a self-
contained unit with its own rules and behavior
OOP
is the
solution
OOP
 Object-Oriented Programming (OOP) was developed to address many of the issues
inherent in unstructured and procedural programming

 OOP organizes data and behavior into objects, which can encapsulate both state
(data) and behavior (functions or methods)

 This makes the code more modular, reusable, and easier to manage
Classes and objects
Class (blueprint)

A class defines what a specific type of thing "knows" (data) and what it can "do" (functions). It
doesn't represent a specific item; it represents the idea of that item.
Attributes: These are variables that store data about the class (e.g., color, size)
Methods: These are functions defined inside the class that describe its actions
Object
(instance)

An object is a specific "instance" created from the class. While the class says "all cars have a color,"
the object says "this specific car is Red." You can create as many objects as you want from a single
class
Classes and objects
Example
Class and object attributes
Class attributes (shared traits)
A Class Attribute is a variable that is shared by all instances of that class. It is defined directly inside the
class but outside of any methods.
• It lives in the class itself
• Every object created from that class can see and use it
• Best used for constants or data that should be exactly the same for every member of the group (e.g.,
the species of an animal or the name of a company)

Object attributes (unique


traits)
An Instance Attribute is unique to a specific object. These are usually defined inside the __init__ method
using the self keyword.
• It lives in a specific object
• Only that specific object can see it
• Best for data that varies from one individual to another (e.g., a person's name, a car's serial number,
or a dog's age)
Class and object attributes
Example

Output
Class constructor and methods
Constructor: __init__
The constructor is a special method that Python calls automatically when you create a new object. Its
main job is to initialize (set up) the attributes of the object.
Syntax: It is always named __init__
Self parameter: You’ll notice self is always the first argument. It represents the specific object being
created, allowing Python to distinguish "this" object's data from another's
Methods:
Methods are functions defined inside a class. They define the behavior of an object, what it can actually
do with its data. Instance methods are the most common and they take self as first argument to access
object’s data
Class constructor and methods
Example
Class constructor and methods
Types of methods:
1. Instance methods:
The most common and they take self as first argument to access object’s data. Have access to both class
and object attributes
2. Static methods:
Static methods are like regular functions that happen to live inside a class. They don't know anything
about the class or the object. They use @staticmethod decorator and take no special first argument like
self or cls. They cannot access class or instance attributes
3. Class methods:
Class methods belong to the class itself rather than any specific object. If you change something via a
class method, it affects the blueprint for everyone. They use the @classmethod decorator and take cls
as first argument. They can only access class attributes and cannot see object related data
Types of methods
Example

Output
Core Components of OOP

OOP
OOP

Inheritance Encapsulation Abstraction Polymorphism


Inheritance Encapsulation Abstraction Polymorphism

Allows use of Hiding details It means ‘many


Binding the data and
attributes and and showing only forms’. It has 2
methods and restricts
methods of what is needed. It types: method
the access to object
another class. reduces overloading and
attributes or methods
Parent-child complexity method
relation formed overriding
1. Inheritance
Core Components of OOP

Inheritance is a way to create a new class using the features of an existing class. It allows a
"Child" class to reuse the code of a "Parent" class without having to rewrite it.

Parent Class (Base Class): The class being inherited from. It contains the general features
Child Class (Derived Class): The class that inherits. It gets all features from the parent and can add
its own
Core Components of OOP
Example

Output
Core Components of OOP

Multiple Inheritance

Multiple Inheritance is a feature in


Python where a single "Child" class can
inherit attributes and methods from
more than one "Parent" class.
Core Components of OOP
Method Resolution Order

MRO: MRO stands for Method Resolution Order. It is the set of rules Python follows to decide which
class's method to use when you call a method on an object, especially in cases of multiple inheritance.
Without MRO, if two parent classes had the same method name, Python wouldn't know which one to
pick. MRO terminates at object class.

MRO is calculated using C3 Linearization algorithm which follows 3 rules:

o Children First: A child class is always checked before its parents

o Left-to-Right: If a class inherits from multiple parents, they are searched in the order they were
listed in the class definition (from left to right)

o No Duplicates: Each class in the hierarchy is checked only once


Core Components of OOP
Method Resolution Order

The Diamond Problem


The most famous case for MRO is the "Diamond Problem."
Imagine this hierarchy:
•Class A is the base
•Class B and Class C both inherit from A
•Class D inherits from both B and C

Search path will be: D -> B -> C -> A -> object


Core Components of OOP
Super() function

In Python, the super() function is a built-in tool that allows a child class to call methods from its
parent (or a class further up the hierarchy).
While it’s most commonly used inside the constructor (__init__), it can be used for any method.

When you use super(), Python looks at the MRO (Method Resolution Order) and calls the method
from the next class in line. This means you don't have to hardcode the parent class's name, making
your code cleaner and more flexible. There is no need to pass self argument using super() function
Core Components of OOP
Super() function
2. Polymorphism
Core Components of OOP
Polymorphism is a Greek word that means "many forms." In programming, it allows different classes to be treated as
if they were the same base class through a shared set of methods. The importance of polymorphism is that you can
call the same method name on different objects, and each object will respond in its own specific way. It has 2 main
types:

1. Method overriding (run time polymorphism)

This is the most common form of polymorphism in Python. It happens when a Child class provides a specific
implementation of a method that is already defined in its Parent class.

2. Method Overloading (compile time polymorphism)

Python does not support traditional method overloading (having multiple methods with the same name but different
arguments in the same class). If you define multiple methods with the same name, the last one overwrites the
previous ones. However, to achieve this you can use default arguments, variable length positional arguments or
keyword-based overloading).
Core Components of OOP
Method Method
Overriding Overloading
3. Encapsulation
Core Components of OOP
Encapsulation is the process of combining data (attributes) and methods together in a capsule.
Information hiding is the primary purpose of encapsulation. It restricts the outside world to change
the internal state of the object, forcing them to interact via safe interface. Access modifiers
(private, public and protected) are used to encapsulate the important information within a safe or
public territory.

There are no explicit public, private and protected keywords to specify the access of attributes and
methods in python. But you can use the terminology of double underscore before variable or
function name (self.__name) for private attributes or methods and single underscore (self._name)
for protected attributes and methods.
Core Components of OOP
Public Members
These can be accessed from anywhere (inside or outside the class).
Naming: No underscores (e.g., [Link])
Behavior: Accessible to everyone
Protected Members (_)
These are intended for internal use within the class and its subclasses (Inheritance).
Naming: One underscore (e.g., self._balance)
Behavior: It’s a gentleman’s agreement. Python won’t stop you from accessing it, but it’s a signal to other programmers:
"Don't use this unless you're a subclass!"
Private Members (__)
These are highly restricted. They are not easily accessible from outside the class.
Naming: Two underscores (e.g., self.__password)
Behavior: Python performs Name Mangling. It changes the internal name so that a simple call from outside will fail
Core Components of OOP

Output

Runtime error occurs when you try to


access the private attribute of the class.
But here, you can see that protected
attribute can be changed. So, to make it
read-only attribute we use @property
decorator
Core Components of OOP
@property decorator

The @property decorator is the Pythonic way to handle encapsulation. It allows you to treat a method like a
regular attribute, giving you the best of both worlds: the clean syntax of a public variable and the safety of a
private one. Usually, if you want to protect a variable named balance inside Account class, you write
get_balance() and set_balance().
But calling account.get_balance() feels un-pythonic and [Link] is preffered. The @property
decorator allows you to use [Link] while secretly running a function in the background.
Benefits of using @property decorator are:
1. It makes attribute read-only and if you don’t use the .setter then the modification in the attribute will
give an AttributeError
2. You can create virtual attributes that don’t really exists as variables but is calculated on the fly (run-
time).
Core Components of OOP

Example 1
Modifying the attribute using
@property getter and setter
Core Components of OOP

Example 2
Creating attribute on fly
4. Abstraction
Core Components of OOP
Abstraction is the practice of hiding the complex internal details of an application and only showing the
necessary features to the user. In Python, we use Abstraction to define what a class must do, without
dictating how it should do it. For example, when you are using laptop, you are not concerned with how it is
built and its internal structure, you only need to learn mouse and keyboard commands to use it effectively.

Take it as like, a class is telling other classes that if you want to use my methods or functionality then you
have to implement some sort of security (abstract method must be implemented in derived class). An
abstract class has at least one abstractmethod. This method has no implementation.
Using abstraction, base class can put some constraints on derived classes, and derived classes are not
allowed to violate those constraints.
• abstractmethod is the decorator
• abc module contains the implementation of ABC class (abstract base classes)
Core Components of OOP

Example

You might also like