Curs 10
Curs 10
Course 10
CLASSES (INHERITANCE)
Python classes supports both simple and multiple inheritance.
Python 3.x (simple inheritance)
class <name>(Base):
<statement1>
…
<statementn>
d = Derived()
print ("d.X = ",d.x)
print ("d.Y = ",d.y)
CLASSES (INHERITANCE)
Inheritances does not assume that the __init__ function is automatically called for the
base when the derived object is created.
Python 3.x (simple inheritance)
class Base:
def __init__(self):
self.x = 10
d = Derived() Output
print ("d.X = ",d.x) d.X = 10
d.Y = 20
print ("d.Y = ",d.y)
CLASSES (INHERITANCE)
Inheriting from a class will overwrite all base class members (methods or data members).
class Derived(Base):
def Print(self):
print("Derived class")
d = Derived() Output
d.Print() Derived class
CLASSES (INHERITANCE)
Inheriting from a class will overwrite all base class members (methods or data members).
class Derived(Base):
def Print(self):
print("Derived class")
Print function from Base class was completely
d = Derived() overwritten by Print function from the derived class.
d.Print() The code will produce a runtime error.
d.Print(100)
CLASSES (INHERITANCE)
Inheriting from a class will overwrite all base class members (methods or data members).
In this case member “x” from Base class will be overwritten by member “x” from the
derived class.
Python 3.x (simple inheritance)
class Base:
x = 10
class Derived(Base):
x = 20
d = Derived()
print (d.x)
Output
20
CLASSES (INHERITANCE)
Polymorphism works in a similar way. In reality the inheritance is not necessary to
accomplish polymorphism in Python.
Python 3.x (simple inheritance)
class Forma:
def PrintName(self): pass Output
class Square(Forma): Square
def PrintName(self): print("Square") Circle
class Circle(Forma): Rectangle
def PrintName(self): print("Circle")
class Rectangle(Forma):
def PrintName(self): print("Rectangle")
d = Derived()
d.MyFunction()
CLASSES (INHERITANCE)
In case of multiple inheritance, Python derives from the right most class to the left most
class from the inheritance list.
Python 3.x (multiple inheritance)
class BaseA:
def MyFunction(self):
print ("Base A")
class BaseB:
def MyFunction(self): First MyFunction from BaseB
print ("Base B") is added to Derived class
class Derived(BaseA, BaseB):
pass
d = Derived()
d.MyFunction()
CLASSES (INHERITANCE)
In case of multiple inheritance, Python derives from the right most class to the left most
class from the inheritance list.
Python 3.x (multiple inheritance)
class BaseA:
def MyFunction(self):
print ("Base A")
class BaseB: Then MyFunction from class
def MyFunction(self): BaseA will overwrite
print ("Base B") MyFunction from BaseB
class Derived(BaseA, BaseB):
pass
d = Derived()
d.MyFunction()
CLASSES (SPECIAL METHODS)
If we reverse the order (BaseB will be first and BaseA wil be the last one), MyFunction
will print “Base B” instead of “Base A”
Python 3.x (multiple inheritance)
class BaseA:
def MyFunction(self): Output
print ("Base A") Base B
class BaseB:
def MyFunction(self):
print ("Base B")
d = Derived()
d.MyFunction()
CLASSES (SPECIAL METHODS)
Python defines a special set of functions that can be use do add additional properties to
a class. Just like the initialization function (__init__) , these functions start and end with
“__”.
Function Purpose
__repr__, __str__ Called when the object needs to be converted into string
__lt__, __le__, __eq__, __ne__, __gt__, Operators used to compare instances of the same class.
__ge__
__bool__ To evaluate the truth value of an object (instance of a class)
__getattr__, __getattribute__ For attribute look-ups
__setattr__, __delattr__ For attribute operations
__set__, __get__
__len__, __del__, For len / del operators
__setitem__, __getitem__, __contains__, Iterator operators
__reversed__, __iter__, __next__
CLASSES (SPECIAL METHODS)
Python also defines a set of mathematical functions that can be used for the same
purpose:
❖ __add__, __sub__, __mul__, __matmul__, __truediv__, __floordiv__, __mod__, __divmod__,
__pow__, __lshift__, __rshift__, __and__, __xor__, __or__
t = Test()
t2 = Test2()
print (t,”:”,str(t))
print (t2, ”:”, str(t2))
CLASSES (SPECIAL METHODS)
Converting to an integer value.
Python 3.x
class Test:
x = 10
class Test2:
x = 10
def __int__(self): return self.x
t = Test()
t2 = Test2() This code will produce a runtime error because
Value = int(t) Python don’t know how to translate an object of
type Test to an integer
CLASSES (SPECIAL METHODS)
Converting to an integer value.
Python 3.x
class Test:
x = 10
class Test2:
x = 10
def __int__(self): return self.x
t = Test()
t2 = Test2()
Value = int(t2) This code works, Value will be 10
CLASSES (SPECIAL METHODS)
Iterating through a class instance
Python 3.x
class CarList:
Output (Python 3)
cars = ["Dacia","BMW","Toyota"]
Dacia
def __iter__(self):
BMW
self.pos = -1 Toyota
return self
def __next__(self):
self.pos += 1
if self.pos==len(self.cars): raise StopIteration
return self.cars[self.pos]
c = CarList()
for i in c:
print (i)
CLASSES (SPECIAL METHODS)
Using class operators. In this case we overwrite __eq__ (==) operator.
Python 3.x
class Number:
Output
def __init__(self, value):
True
self.x = value
False
def __eq__(self, obj):
return self.x+obj.x == 0
n1 = Number(-5)
n2 = Number(5)
n3 = Number(6)
print (n1==n2)
print (n1==n3)
CLASSES (SPECIAL METHODS)
Overwriting the “in” opertator (__contains__).
Python 3.x
class Number:
Output
def __init__(self, value):
True
self.x = value
False
def __contains__(self, value): True
return str(value) in str(self.x)
n = Number(123)
print (12 in n)
print (5 in n)
print (3 in n)
CLASSES (SPECIAL METHODS)
Overwriting the “len” opertator (__len__).
Python 3.x
class Number:
Output
def __init__(self, value):
3 5 1
self.x = value
def __len__(self, value):
return len(str(self.x))
n1 = Number(123)
n2 = Number(99999)
n3 = Number(2)
print (len(n1),len(n2),len(n3))
CLASSES (SPECIAL METHODS)
Building your own dictionary (overwrite __setitem__ and __getitem__)
Python 3.x
class MyDict:
def __init__(self): self.data = []
def __setitem__(self,key,value): self.data += [(key,str(value))]
def __getitem__(self,key):
for i in self.data:
if i[0]==key:
return i[1]
Output
d = MyDict() python 123
d["test"] = "python"
d["numar"] = 123
print (d["test"],d["numar"])
CLASSES (SPECIAL METHODS)
Building a bit set (overloading operator [])
Python 3.x
class BitSet:
def __init__(self): self.value = 0
def __setitem__(self,index,value):
if value: self.value |= (1 << (index & 31))
else: self.value -= (self.value & (1 << (index & 31))
def __getitem__(self,key): Output
return (self.value & (1 << (index & 31)))!=0 Bit 0 is True
b = BitSet() Bit 1 is False
b[0] = True Bit 2 is True
Bit 3 is False
b[2] = True
Bit 4 is True
b[4] = True Bit 5 is False
for i in range(0,8): Bit 6 is False
print("Bit ",i," is ",b[i]) Bit 7 is False
CONTEXT MANAGER
A context manager is a mechanism where an object is created an notification about the
moment that object is being access and the moment that object is being terminated.
Context managers are used along with with keyword. The objects that available in a
context manager should implement __enter__ and __exit__ methods.
with item1 as alias1, [item2 as alias2 , … itemn as aliasn ]:
<statement 1>
<statement 2>
….
<statement n>
with item1, [item2, … itemn]:
<statement 1>
<statement 2>
….
<statement n>
CONTEXT MANAGER
Whenever a with command is encounter, the following steps happen:
1. All items are evaluated
2. For all items __enter__ is called
3. If aliases are provided, the result of the __enter__ method is store into the alias
4. The block within the with is executed
5. If an exception appears, __exit__ is called and information related to the exception
(type, value and traceback) are provided as parameters. If the __exit__ method
returns false, the exception is re-raised. If the __exit__ method returns true, the
exception is ignored.
6. If no exception appear, __exit__ is called with None parameters for (type, value and
traceback). The result from the __exit__ method will be ignored.
CLASSES (SPECIAL METHODS)
File context manager
Python 3.x
class CachedFile:
Output
def __init__(self,fileName):
__enter__ is called
self.data = "" __exit__ is called
self.fileName = fileName
def __enter__(self):
print("__enter__ is called")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("__exit__ is called")
open(self.fileName,"wt").write(self.data)
return False
with CachedFile("Test.txt") as f:
f.data = "Python course"