0% found this document useful (0 votes)
10 views14 pages

OOP Unit 2 (Part 2)

The document discusses key concepts in Object-Oriented Programming (OOP) with Python, including multiple inheritance, decorators, static and class methods, and file I/O. It explains how multiple inheritance allows a class to inherit from multiple parent classes and introduces the method resolution order (MRO) to resolve conflicts. Additionally, it covers the use of decorators to modify function behavior, the differences between static and class methods, and various file handling modes and operations in Python.

Uploaded by

ksanjot247
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views14 pages

OOP Unit 2 (Part 2)

The document discusses key concepts in Object-Oriented Programming (OOP) with Python, including multiple inheritance, decorators, static and class methods, and file I/O. It explains how multiple inheritance allows a class to inherit from multiple parent classes and introduces the method resolution order (MRO) to resolve conflicts. Additionally, it covers the use of decorators to modify function behavior, the differences between static and class methods, and various file handling modes and operations in Python.

Uploaded by

ksanjot247
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Understanding

OOP with Python


Unit 2(part 2)
By Prof.Hitesh Prajapati
Multiple Inheritance and the Lookup
Multiple inheritance in Python allows a class to inherit attributes and
methods from multiple parent classes. This feature provides flexibility
but can sometimes lead to complications, such as method naming
conflicts or ambiguity. To address these issues, Python uses a method
resolution order (MRO) mechanism, which determines the order in
which base classes are considered during method lookup.

When a class inherits from multiple classes, it inherits both attributes


and methods. The super() function is used to call methods from parent
classes. In Python, super() is used to access the parent class’s methods
and attributes, and it takes arguments to specify which parent class to
access.
Example
class parent:
In this example, the C def show(self):
class inherits from print("Parent class")
both A and B, and class child:
overrides the show() def show(self):
method. When C’s print("Child class")
show() method is
called, it uses super() class C(parent,child):
to access and call the def __init__(self):
super().show()
show() methods from super(parent,self).show()
A and B, respectively,
in the correct order, as obj = C()
determined by the Output:
MRO. Parent class
Child class
Decorators

Python decorators are a powerful feature that enables you to


modify or extend the behavior of a function without altering its
source code. They achieve this by wrapping the original function
with a new function, called the wrapper, which contains the
desired modifications.

Define a decorator function: A decorator function takes a function


as an argument and returns a new function, which is the wrapper.
The decorator function is denoted by the @ symbol
Decorators
def my_decorator(func):
def wrapper():
print("Something before the function.")
func()
print("Something after the function.")
return wrapper

@my_decorator
def say_hello():
print("Hello!")
say_hello()

In the example above, say_hello is the original function, and my_decorator


is the decorator function. After applying the decorator, say_hello is replaced
with the wrapper function returned by my_decorator.
Decorators

Apply the decorator: When you apply a decorator to a function using the
@ symbol, Python replaces the original function with the wrapper
returned by the decorator.

The wrapper function: The wrapper function contains the desired


modifications to the original function. In this case, it prints messages
before and after calling the original function.

When you call the decorated function (say_hello()), you’ll see the
output:
Something before the function.
Hello!
Something after the function.
Static and Class Methods
In Python, a static method is a method that is bound to a class rather than an
instance of the class. It does not have access to instance-specific data and is
primarily used for utility functions that don’t depend on the state of the object.

class Name:
@staticmethod
def add(x, y):
return x + y

print(Name.add(5,4))

Here, add is a static method because it doesn’t depend on any instance-specific


data.
Static and Class Methods
A class method, on the other hand, is a method that is bound to a class and has
access to class-specific data. It is defined using the @classmethod decorator:

class Employee:
num_employees = 0

def __init__(self, name, salary): Employee("hitesh", 1000)


self.name = name
Employee.display_num_employ
self.salary = salary
ees()
Employee.num_employees += 1

@classmethod
def display_num_employees(cls):
print(f"Number of employees: {cls.num_employees}")
Static and Class Methods
The class method in Python is a method, which is bound to the class but not the object of that class.
The static methods are also same but there are some basic differences. For class methods, we need to
specify @classmethod decorator, and for static method @staticmethod decorator is used.

from datetime import date as dt


class Employee: @classmethod
def __init__(self, name, age): def emp_from_year(emp_class, name, year):
self.name = name return emp_class(name, dt.today().year - year)
self.age = age
def __str__(self):
@staticmethod return 'Employee Name: {} and Age: {}'.format(self.name, self.age)
def isAdult(age):
if age > 18: print(Employee('Dhiman', 25))
return True print( Employee.emp_from_year('Subhas', 1987))
else: print(Employee.isAdult(25))
return False print(Employee.isAdult(16))
Static and Class Methods
File I/O
Python provides various ways to interact with files, including reading and
writing text and binary data. Here’s a comprehensive overview:
Modes
1. Text Mode :
● 'r': Read-only, starts at the beginning of the file.
● 'w': Write-only, truncates the file to zero length if it exists,
creates a new file if it doesn’t.
● 'a': Append-only, starts at the end of the file.
● 'r+', 'w+', 'a+': Read-write, starts at the beginning of the file (or
end for 'a+').
2. Binary Mode ('rb', 'wb', 'ab', 'r+b', 'w+b', 'a+b'):
Same as text modes, but for binary data.
File I/O
open(file_name, mode)

● file_name: The name of the file to open.


● mode: The mode in which to open the file (e.g., 'r', 'w', 'rb', etc.).

Reading from a File

● read(size=-1): Reads up to size bytes from the file. Default is to


read the entire file.
● readline(): Reads a single line from the file.
● readlines(): Reads all lines from the file into a list.
File I/O
Writing to a File

● write(string): Writes string to the file.


● writelines(lines): Writes a list of strings to the file.

File Object Attributes

● closed: A boolean indicating whether the file is closed.


● name: The name of the file.
● mode: The mode in which the file was opened.
File I/O
fo = open("hello.txt","wb")
with open("hello.txt", "a") as
print ("Name of the file: ", fo.name)
file:
print ("Closed or not : ", fo.closed)
file.write("This is an
print ("Opening mode : ", fo.mode)
appended line.\n")

with open("image.png", "rb") as


with open("hello.txt", "w") as file:
file:
file.write("Hello, World!")
image_data = file.read()
print(image_data)
with open("hello.txt", "r") as file:
content = file.read()
print(content)

You might also like