CH7 Python ObjectOriented

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 42

Python Object Oriented

J. Merhej
Outline
 Classes  Inheritance
 Defining classes  Print an object
 Using classes  issubclass()
 Encapsulation
 isinstance()
 Inheritance and Subclasses
 is operator
 Variables
 Multiple inheritance
 Instance variables
 Private variables  Creating your own
 Class variables exceptions
 Class built-in functions  Cisco: MODULE 3: OBJECT-
 Methods ORIENTED PROGRAMMING
 Inner life of classes and
objects
 Introspection and Reflection

11/04/2024 Python Object Oriented 2


Classes
Defining classes
Using classes
Encapsulation
Inheritance and Subclases
Defining Classes
class name:
"documentation"
statements
-or-
class name(base1, base2, ...):
...

Most, statements are method definitions:


def name(self, arg1, arg2, ...):
...
May also be class variable assignments

11/04/2024 Python Object Oriented 4


Using Classes
To create an instance, simply call the class object:
x = Stack() # no 'new' operator!
To use methods of the instance, call using dot notation:
x.empty()
x.push(1)
To inspect instance variables, use dot notation:
x.items

11/04/2024 Python Object Oriented 5


Classes

11/04/2024 Python Object Oriented 6


Stack Example – Procedural Vs OO approach
stack = [] class Stack:
def push(val): def __init__(self):
self.__stack_list = []
stack.append(val)
def push(self, val):
def pop(): self.__stack_list.append(val)
val = stack[-1]
del stack[-1] def pop(self):
val = self.__stack_list[-1]
return val
del self.__stack_list[-1]
push(3) return val
push(2) stack_object = Stack()
push(1) stack_object.push(3)
stack_object.push(2)
print(pop())
stack_object.push(1)
print(pop())
print(stack_object.pop())
print(pop()) print(stack_object.pop())
print(stack_object.pop())

11/04/2024 Python Object Oriented 7


Encapsulation in Python
 When any class component has a name starting with two underscores (__), it
becomes private - this means that it can be accessed only from within the class.

 You cannot see it from the outside world. This is how Python implements the
encapsulation concept.

class Stack: class Stack:


def __init__(self): def __init__(self):
self.stack_list = [] self.__stack_list = []

stack_object = Stack() stack_object = Stack()


print(len(stack_object.stack_list)) print(len(stack_object.__stack_list))
--- 0

11/04/2024 Python Object Oriented 8


Class Inheritance

11/04/2024 Python Object Oriented 9


Class Inheritance
class Stack: def push(self, val):
def __init__(self): self.__sum += val
self.__stack_list = [] Stack.push(self, val)

def push(self, val): def pop(self):


self.__stack_list.append(val) val = Stack.pop(self)
self.__sum -= val
def pop(self): return val
val = self.__stack_list[-1]
del self.__stack_list[-1]
return val stack_object = AddingStack()

for i in range(5):
class AddingStack(Stack): stack_object.push(i)
def __init__(self): print(stack_object.get_sum())
Stack.__init__(self)
self.__sum = 0 for i in range(5):
print(stack_object.pop())
def get_sum(self):
return self.__sum

11/04/2024 Python Object Oriented 10


Variables
Instance variables
Private variables
Class variables

11/04/2024 Python Object Oriented 11


Instance Variables
 Each object carries its own set of properties - they don't interfere with
one another in any way. Such variables (properties) are called instance
variables.
 Modifying an instance variable of any object has no impact on all the
remaining objects.
 Python objects, when created, are gifted with a small set of predefined
properties and methods. Each object has got them, whether you want
them or not. One of them is a variable named __dict__ (it's a
dictionary).
 The variable contains the names and values of all the properties
(variables) the object is currently carrying. Let's make use of it to safely
present an object's contents.

11/04/2024 Python Object Oriented 12


Instance Variables
class ExampleClass:
def __init__(self, val = 1):
self.first = val
def set_second(self, val):
self.second = val
example_object_1 = ExampleClass()
example_object_2 = ExampleClass(2)
example_object_2.set_second(3)
example_object_3 = ExampleClass(4)
example_object_3.third = 5
print(example_object_1.__dict__)
print(example_object_2.__dict__)
print(example_object_3.__dict__)-
{'first': 1}
{'first': 2, 'second': 3}
{'first': 4, 'third': 5}
11/04/2024 Python Object Oriented 13
Private variables
class ExampleClass: Once added two
def __init__(self, val = 1): underscores (__) in front
self.__first = val of variable  makes the
instance variable private -
def set_second(self, val = 2):
self.__second = val
it becomes inaccessible
from the outer world.
example_object_1 = ExampleClass()
print(example_object_1._ExampleClass__first)
example_object_2 = ExampleClass(2) In this case, Python puts a
class name before your
example_object_2.set_second(3) name; it puts an
example_object_3 = ExampleClass(4) additional underscore at
example_object_3.__third = 5
the beginning.
print(example_object_1.__dict__)
print(example_object_2.__dict__)
print(example_object_3.__dict__) TRY IT

11/04/2024 Python Object Oriented 14


Class variables
 A class variable is a property which exists in just one
copy and is stored outside any object.
Note: no instance variable exists if there is no object in
the class; a class variable exists in one copy even if
there are no objects in the class.
Class variables aren't shown in an object's __dict__
(this is natural as class variables aren't parts of an
object).
a class variable always presents the same value in all
class instances (objects)

11/04/2024 Python Object Oriented 15


Class variables
class ExampleClass:
counter = 0
def __init__(self, val = 1):
self.__first = val
ExampleClass.counter += 1

example_object_1 = ExampleClass()
example_object_2 = ExampleClass(2)
example_object_3 = ExampleClass(4)

print(example_object_1.__dict__, example_object_1.counter)
print(example_object_2.__dict__, example_object_2.counter)
print(example_object_3.__dict__, example_object_3.counter) --
{'_ExampleClass__first': 1} 3 {'_ExampleClass__first': 2} 3
{'_ExampleClass__first': 4} 3

11/04/2024 Python Object Oriented 16


Class Built-In functions

11/04/2024 Python Object Oriented 17


Checking an attribute's existence
class ExampleClass: class ExampleClass:
def __init__(self, val): def __init__(self, val):
if val % 2 != 0: if val % 2 != 0:
self.a = 1 self.a = 1
else: else:
self.b = 1 self.b = 1

example_object = ExampleClass(1)
example_object = ExampleClass(1) print(example_object.a)
print(example_object.a)
print(hasattr(example_object, 'b'))
try: print(hasattr(ExampleClass, ‘a'))
print(example_object.b)
except AttributeError:
pass  1
 False
--1  False

11/04/2024 Python Object Oriented 18


Built-in class functions
hasattr(obj,name) to check if an attribute exists or
not.
getattr(obj, name[, default]) : to access the attribute of
object.
setattr(obj,name,value) : to set an attribute. If attribute
does not exist, then it would be created.
delattr(obj, name) : to delete an attribute.

11/04/2024 Python Object Oriented 19


Methods
Inner life of classes and objects
Introspection and Reflection

11/04/2024 Python Object Oriented 20


Methods
As you already know, a method is a function embedded inside a
class. There is one fundamental requirement - a method is
obliged to have at least one parameter (there are no such thing as
parameter less methods - a method may be invoked without an
argument, but not declared without parameters).

The first (or only) parameter is usually named self. We suggest


that you follow the convention - it's commonly used, and you'll
cause a few surprises by using other names for it.
The name self suggests the parameter's purpose - it identifies the
object for which the method is invoked.

11/04/2024 Python Object Oriented 21


Methods – Self parameter
class Classy: class Classy:
def __init__(self, value): varia = 2
self.var = value def method(self):
print(self.varia, self.var)

obj_1 = Classy("object")
obj = Classy()
print(obj_1.var) - ‘object’ obj.var = 3
obj.method()  2 3

11/04/2024 Python Object Oriented 22


Inner life of classes and objects
__dict__ is a dictionary of object or class variables
 Another built-in property worth mentioning is __name__,
which is a string containing the name of the class.
Function type(), which is able to find a class which has
been used to instantiate any object.
__module__ is a string- it stores the name of the module
which contains the definition of the class.
__bases__ is a tuple. The tuple contains classes (not class
names) which are direct superclasses for the class.

11/04/2024 Python Object Oriented 23


Inner life of classes and objects
class Classy: class Classy: class Classy:
varia = 1 pass pass
def __init__(self):
self.var = 2
print(Classy.__name__) print(Classy.__module__)
def method(self): obj = Classy() obj = Classy()
pass print(type(obj).__name__) print(obj.__module__)

def __hidden(self):  Classy  _main__


pass Classy  __main__

obj = Classy()
print(obj.__dict__)
print(Classy.__dict__)
TRY IT

11/04/2024 Python Object Oriented 24


Inner life of classes and objects
class SuperOne:
pass

class SuperTwo:
pass

class Sub(SuperOne, SuperTwo):


pass

def printBases(cls):
print('( ', end='')

for x in cls.__bases__:
print(x.__name__, end=' ')
print(')')

printBases(SuperOne)
printBases(SuperTwo)
printBases(Sub)  ( object ) ( object ) ( SuperOne SuperTwo )

11/04/2024 Python Object Oriented 25


Introspection and Reflection
• introspection, class MyClass:
which is the pass
ability of a
program to obj = MyClass()
examine the type obj.a = 1
or properties of obj.b = 2
obj.i = 3
an object at
obj.ireal = 3.5
runtime;
obj.integer = 4
• reflection, which obj.z = 5
goes a step
further, and is def incIntsI(obj):
the ability of a for name in obj.__dict__.keys():
program to if name.startswith('i'):
manipulate the val = getattr(obj, name)
values, if isinstance(val, int):
properties setattr(obj, name, val + 1)
and/or functions
of an object at print(obj.__dict__)
runtime. incIntsI(obj)
print(obj.__dict__) TRY IT

11/04/2024 Python Object Oriented 26


Inheritance
Print an object
issubclass()
isinstance()
is operator

11/04/2024 Python Object Oriented 27


Inheritance – Print an object
 When Python needs any class/object to be presented as a string, it tries to invoke a
method named __str__() from the object and to use the string it returns.
 The default __str__() method returns the previous string - ugly and not very
informative. You can change it just by defining your own method of the name.

class Star: class Star:


def __init__(self, name, galaxy):
def __init__(self, name, self.name = name
galaxy): self.galaxy = galaxy
self.name = name
self.galaxy = galaxy def __str__(self):
return self.name + ' in ' + self.galaxy
sun = Star("Sun", "Milky Way")
print(sun)
<__main__.Star object at sun = Star("Sun", "Milky Way")
0x79025c7854b0> print(sun)
Sun in Milky Way

11/04/2024 Python Object Oriented 28


Inheritance: issubclass()
class Vehicle:
 Issubclass(class1 pass
,class2): can
check if a class LandVehicle(Vehicle):
particular class pass
is a subclass of
any other class.
class TrackedVehicle(LandVehicle):
pass

for cls1 in [Vehicle, LandVehicle, TrackedVehicle]:


for cls2 in [Vehicle, LandVehicle, TrackedVehicle]:
True False False print(issubclass(cls1, cls2), end="\t")
True True False print()
True True True

11/04/2024 Python Object Oriented 29


Inheritance: class Vehicle:
pass
isinstance() class LandVehicle(Vehicle):
pass
 Isinstance(obj,cls
) : to detect if an class TrackedVehicle(LandVehicle):
object is an pass
instance of a
class
my_vehicle = Vehicle()
my_land_vehicle = LandVehicle()
my_tracked_vehicle = TrackedVehicle()

for obj in [my_vehicle, my_land_vehicle,


my_tracked_vehicle]:
for cls in [Vehicle, LandVehicle, TrackedVehicle]:
print(isinstance(obj, cls), end="\t")
print() ------

11/04/2024 Python Object Oriented 30


class SampleClass:
def __init__(self, val):
Inheritance: is operator self.val = val
 The is operator checks
whether two variables object_1 = SampleClass(0)
(object_one and object_two object_2 = SampleClass(2)
here) refer to the same object_3 = object_1
object_3.val += 1
object.
 Assigning a value of an print(object_1 is object_2)
object variable to another print(object_2 is object_3)
variable doesn't copy the print(object_3 is object_1)
print(object_1.val, object_2.val, object_3.val)
object.
string_1 = "Mary had a little "
string_2 = "Mary had a little lamb"
False
string_1 += "lamb"
False
True print(string_1)
1 2 1
Mary had a little lamb print(string_1 == string_2, string_1 is string_2)
True False
11/04/2024 Python Object Oriented 31
Inheritance Example
super() function, which accesses the superclass without needing to know its name:

class Super: class Super:


supVar = 1
def __init__(self, name):
self.name = name
class Sub(Super):
def __str__(self): subVar = 2
return "My name is " + self.name + "."

obj = Sub()
class Sub(Super):
def __init__(self, name): print(obj.subVar)
Super.__init__(self, name) print(obj.supVar)

obj = Sub("Andy")
print(obj)

11/04/2024 Python Object Oriented 32


100 101 102
Three level Inheritance 200 201 202
300 301 302

class Level1: class Level3(Level2):


variable_1 = 100 variable_3 = 300
def __init__(self): def __init__(self):
self.var_1 = 101 super().__init__()
self.var_3 = 301
def fun_1(self):
return 102 def fun_3(self):
return 302
class Level2(Level1):
variable_2 = 200
def __init__(self): obj = Level3()
super().__init__()
self.var_2 = 201 print(obj.variable_1, obj.var_1, obj.fun_1())
print(obj.variable_2, obj.var_2, obj.fun_2())
def fun_2(self): print(obj.variable_3, obj.var_3, obj.fun_3())
return 202

11/04/2024 Python Object Oriented 33


Multiple Inheritance
class SuperA:
var_a = 10
def fun_a(self):
return 11

class SuperB: 10 11
var_b = 20 20 21
def fun_b(self):
return 21

class Sub(SuperA, SuperB):


pass

obj = Sub()

print(obj.var_a, obj.fun_a())
print(obj.var_b, obj.fun_b())

11/04/2024 Python Object Oriented 34


Multiple Inheritance
class Level1:
var = 100
def fun(self):
return 101

class Level2(Level1):
200 201
var = 200
def fun(self):
return 201

class Level3(Level2):
pass

obj = Level3()

print(obj.var, obj.fun())

11/04/2024 Python Object Oriented 35


Multiple Inheritance
class Left:
var = "L"
var_left = "LL" Python looks for object components in
def fun(self): the following order:
return "Left"
• inside the object itself;
class Right: • in its superclasses, from bottom to
var = "R" top;
var_right = "RR"
• if there is more than one class on a
def fun(self):
return "Right" particular inheritance path, Python
scans them from left to right.

class Sub(Left, Right):


pass

obj = Sub() L LL RR Left


print(obj.var, obj.var_left, obj.var_right,
obj.fun())

11/04/2024 Python Object Oriented 36


class MyZeroDivisionError(ZeroDivisionError):
Creating your own pass
exceptions def do_the_division(mine):
if mine:
print('some worse news')
raise MyZeroDivisionError("some worse news")
My division by zero
else:
False
print('some bad news')
some bad news
raise ZeroDivisionError("some bad news")
Division by zero
True
for mode in [False, True]:
some worse news
try:
Division by zero
print(mode)
some bad news
do_the_division(mode)
Original division by
except ZeroDivisionError:
zero
print('Division by zero')
some worse news
My division by zero
for mode in [False, True]:
try:
do_the_division(mode)
except MyZeroDivisionError:
print('My division by zero')
except ZeroDivisionError:
print('Original division by zero')
11/04/2024 Python Object Oriented 37
class PizzaError(Exception):
Creating your own def __init__(self, pizza, message):
Exception.__init__(self, message)
exceptions self.pizza = pizza

class TooMuchCheeseError(PizzaError):
def __init__(self, pizza, cheese, message):
Pizza ready!
PizzaError.__init__(self, pizza, message)
too much cheese : 110
self.cheese = cheese
no such pizza on the
menu : mafia
def make_pizza(pizza, cheese):
if pizza not in ['margherita', 'capricciosa', 'calzone']:
raise PizzaError(pizza, "no such pizza on the menu")
if cheese > 100:
raise TooMuchCheeseError(pizza, cheese, "too much
cheese")
print("Pizza ready!")

for (pz, ch) in [('calzone', 0), ('margherita', 110), ('mafia', 20)]:


try:
make_pizza(pz, ch)
except TooMuchCheeseError as tmce:
print(tmce, ':', tmce.cheese)
except PizzaError as pe:
print(pe, ':', pe.pizza)
11/04/2024 Python Object Oriented 38
Python vs Java

11/04/2024 Python Object Oriented 39


Python vs. Java
 Hello World

 String Operations

11/04/2024 Python Object Oriented 40


Python vs. Java
 Collections

11/04/2024 Python Object Oriented 41


Python vs. Java
 Class and Inheritance

11/04/2024 Python Object Oriented 42

You might also like