Curs 9
Curs 9
Course 9
CLASSES
Classes exists in Python but have a different understanding about their functionality than
the way classes are defined in C-like languages. Classes can be defined using a special
keyword: class
Python 3.x
class <name>:
<statement1>
…
<statementn>
p = Point()
print (p.GetX())
Output
0
CLASSES
Defining a function within a class without having the first parameter self means that that
function is a static function for that class.
Python 3.x Python 3.x
class Point: class Point:
def __init__(self): def __init__(self):
self.x = 0 self.x = 0
self.y = 0 self.y = 0
def GetY(): def GetY():
return self.y print(”Test”)
p = Point() Point.GetY()
print (p.GetY())
Output
Execution error Python 3: will print “Test” on the screen
(GetY is static)
CLASSES
A data member can also be defined directly in the class definition. However, if mutable
object are used the behavior is different (similar in terms of behavior to a static
variable)
Python 3.x Python 3.x
class Point: class Point:
x = 0 numbers = [1,2,3]
y = 0 def AddNumber(self,n):
self.numbers += [n]
p1 = Point() p1 = Point()
p2 = Point() p2 = Point()
p1.x = 10 p1.AddNumber(4)
p2.x = 20 Output p2.AddNumber(5)
print (p1.x,p2.x) 10 20
print (p1.numbers) Output
print (p2.numbers) [1,2,3,4,5]
[1,2,3,4,5]
CLASSES
To avoid problems with mutable objects it is better to defined them in a constructor
(__init__) function:
Python 3.x
class Point:
def __init__(self):
self.numbers = [1,2,3]
def AddNumber(self,n):
self.numbers += [n]
p1 = Point()
p2 = Point()
p1.AddNumber(4)
p2.AddNumber(5)
print (p1.numbers) Output
print (p2.numbers) [1,2,3,4]
[1,2,3,5]
CLASSES
It is not required for two instances of the same class to have the same members. A class
instance is more like a dictionary where each key represent either a member function or
a data member
Python 3.x
class Point:
def __init__(self):
self.x = 0
self.y = 0
p1 = Point()
p2 = Point()
p1.z = 10
print (p1.x,p1.y,p1.z)
Output
0 0 10
CLASSES
It is not required for two instances of the same class to have the same members. A class
instance is more like a dictionary where each key represent either a member function or
a data member
Python 3.x
class Point:
def __init__(self):
self.x = 0
self.y = 0
p1 = Point()
p2 = Point() Error during runtine. “p2” does not have a
p1.z = 10 data member “z” (only “p1” has a data
print (p1.x,p1.y,p2.z) member “z”)
CLASSES
It is not required for two instances of the same class to have the same members. A class
instance is more like a dictionary where each key represent either a member function or
a data member
Python 3.x
class Point:
def __init__(self):
self.x = 0
self.y = 0
p1 = Point()
p2 = Point()
p1.z = 10
print ("x" in dir(p1))
print ("z" in dir(p1)) Output
print ("z" in dir(p2)) True
True
False
CLASSES
We can write an equivalent representation of the functionality done by classes by using
dictionaries:
Python 3.x Python 3.x (dictionary representation)
class Point: def PointClass__init__(obj):
def __init__(self): obj["x"] = 0
self.x = 0 obj["y"] = 0
self.y = 0
p1 = Point() Point = { "__init__":PointClass__init__ }
p2 = Point() p1 = dict(Point)
p1.z = 10 p1["__init__"](p1)
p2 = dict(Point)
p2["__init__"](p2)
p1["z"] = 10
CLASSES
We can write an equivalent representation of the functionality done by classes by using
dictionaries:
Python 3.x Python 3.x (dictionary representation)
class Point: def PointClass__init__(obj):
def __init__(self): obj["x"] = 0
self.x = 0 obj["y"] = 0
self.y = 0
p1 = Point() Point = { "__init__":PointClass__init__ }
p2 = Point() p1 = dict(Point)
p1.z = 10 p1["__init__"](p1)
p2 = dict(Point)
p2["__init__"](p2)
p1["z"] = 10
CLASSES
We can write an equivalent representation of the functionality done by classes by using
dictionaries:
Python 3.x Python 3.x (dictionary representation)
class Point: def PointClass__init__(obj):
def __init__(self): obj["x"] = 0
self.x = 0 obj["y"] = 0
self.y = 0
p1 = Point() Point = { "__init__":PointClass__init__ }
p2 = Point() p1 = dict(Point)
p1.z = 10 p1["__init__"](p1)
p2 = dict(Point)
p2["__init__"](p2)
p1["z"] = 10
CLASSES
We can write an equivalent representation of the functionality done by classes by using
dictionaries:
Python 3.x Python 3.x (dictionary representation)
class Point: def PointClass__init__(obj):
def __init__(self): obj["x"] = 0
self.x = 0 obj["y"] = 0
self.y = 0
p1 = Point() Point = { "__init__":PointClass__init__ }
p2 = Point() p1 = dict(Point)
p1.z = 10 p1["__init__"](p1)
p2 = dict(Point)
p2["__init__"](p2)
p1["z"] = 10
CLASSES
What happens if a class has some objects defined directly in class ?
Python 3.x Python 3.x (dictionary representation)
class Test: numbers_vector = [1,2,3]
numbers = [1,2,3] def TestClass_AddNumber(obj,n):
def AddNumber(self,n): obj["numbers"]+=[n]
self.numbers += [n]
p1 = Test() TestClass = {
p2 = Test() "AddNumber":TestClass_AddNumber,
p1.AddNumber(4) "numbers":numbers_vector
p2.AddNumber(5) }
m = MyClass()
print (m.x,"=>",type(m.x))
m.x = "a string"
print (m.x,"=>",type(m.x))
Output
10 => <class 'int'>
a string => <class 'str'>
CLASSES
The same can be applied for class methods – however in this case there are some
restrictions related to the self keyword.
Python 3.x
class MyClass:
x = 10
y = 20
def Test(self,value):
return ((self.x+self.y)/2 == value)
def MyFunction(self,v1,v2):
return str(v1+v2)+" - "+str(self.x)+","+str(self.y)
m = MyClass()
print (m.Test(15),m.Test(16))
m.Test = m.MyFunction Output
print (m.Test(1,2)) True False
3 - 10,20
CLASSES
The same can be applied for class methods – however in this case there are some
restrictions related to the self keyword.
Python 3.x
class MyClass:
x = 10
y = 20
def Test(self,value):
return ((self.x+self.y)/2 == value)
def MyFunction(self,v1,v2):
return str(v1+v2)+" - "+str(self.x)+","+str(self.y)
Runtime error because “MyFunction” is a
m = MyClass() method that needs to be bound to an
print (m.Test(15),m.Test(16)) object instance !
m.Test = MyClass.MyFunction
print (m.Test(1,2))
CLASSES
The same can be applied for class methods – however in this case there are some
restrictions related to the self keyword.
Python 3.x
class MyClass:
x = 10
y = 20
def Test(self,value):
return ((self.x+self.y)/2 == value)
def MyFunction(self,v1,v2):
return str(v1+v2)+" - "+str(self.x)+","+str(self.y)
m = MyClass()
print (m.Test(15),m.Test(16))
m.Test = MyClass().MyFunction Output
print (m.Test(1,2)) True False
3 - 10,20
CLASSES
The same can be applied for class methods – however in this case there are some
restrictions related to the self keyword.
Python 3.x
class MyClass:
x = 10
y = 20
def Test(self,value):
return ((self.x+self.y)/2 == value)
def MyFunction(self,v1,v2):
return str(v1+v2)+" - "+str(self.x)+","+str(self.y)
m = MyClass()
m2 = MyClass()
print (m.Test(15),m.Test(16)) Output
m.Test = m2.MyFunction True False
print (m.Test(1,2)) 3 - 10,20
CLASSES
Methods are bound to the self object of the class they were initialized in. Even if you
associate a method from a different class to a new method, the self will belong to the
original class.
Python 3.x
class MyClass:
x = 10
def Test(self,value):
return ((self.x+self.y)/2 == value)
def MyFunction(self,v1,v2):
return str(v1+v2)+" - "+str(self.x)
m = MyClass()
m2 = MyClass()
m2.x = 100
m.Test = m2.MyFunction m.Test actually refers to Output
print (m.Test(1,2)) m2.MyFunction 3 – 100
print (m.MyFunction(1,2)) 3 - 10
CLASSES
A method from another class can also be used, but it will refer to the self from the
original
Python 3.xclass.
class MyClass:
x = 10
y = 20
def Test(self,value):
return ((self.x+self.y)/2 == value)
class AnotherClass:
def MyFunction(self,v1,v2):
return str(v1+v2)+" - "+str(self.x)+","+str(self.y)
m = MyClass()
print (m.Test(15),m.Test(16))
m.Test = AnotherClass().MyFunction The code will produce a runtime error
print (m.Test(1,2)) because the self object from AnotherClass
does not have “x” and “y” members.
CLASSES
Normal functions can also be used. However, in this case, the self object will not be send
when calling them and it will not be accessible.
Python 3.x
class MyClass:
x = 10
y = 20
def Test(self,value):
return ((self.x+self.y)/2 == value)
def MyFunction(self,v1,v2):
return str(v1+v2)
m = MyClass()
print (m.Test(15),m.Test(16))
m.Test = MyFunction Output
print (m.Test(1,2)) True False
3
CLASSES
Similarly a class method can be associated (linked) to a normal variable and used as
such. It will be able to use the self and it will be affected if self members are changed.
Python 3.x
class MyClass:
x = 10
def MyFunction(self,v1,v2):
return str(v1+v2)+" – self.x:"+str(self.x)
m = MyClass()
fnc = m.MyFunction
print (fnc(15,35))
m.x = 123
print (fnc(15,35))
Output
50 - self.x: 10
50 - self.x: 123
CLASSES
self object is assign during the construction of an object. This means that a function can
be defined outside the class and used within the class if it is set during the construction
phase.
Python 3.x
def MyFunction(self,v1,v2):
return str(v1+v2)+" - X = "+str(self.x)
class MyClass:
x = 10
Test = MyFunction
m = MyClass()
m2 = MyClass() Output
m2.x = 15 3 - X = 10
print (m.Test(1,2)) 30 - X = 15
print (m2.Test(10,20))
CLASSES
This type of assignment can not be done within the constructor method (__init__), it must
be done through direct declaration in the class body.
Python 3.x
def MyFunction(self,v1,v2):
return str(v1+v2)+" - X = "+str(self.x)
class MyClass:
x = 10
def __init__(self):
self.Test = MyFunction
m = MyClass()
m2 = MyClass()
m2.x = 15 The code will produce a runtime error
print (m.Test(1,2)) because MyFunction is not bound to any self
print (m2.Test(10,20)) at this point
CLASSES
The same error will appear if we try to link a method from a class using it’s instance with
a non-class function.
Python 3.x
def MyFunction(self,v1,v2):
return str(v1+v2)+" - X = "+str(self.x)
class MyClass:
x = 10
m = MyClass()
m2.Test = MyFunction
p = Point()
p.x = 100
p.y = 200
p_3d = Point()
p_3d.x = 10
Output
p_3d.y = 20
P = 100 200
p_3d.z = 30
3D= 10 20 30
print ("P = ",p.x,p.y)
print ("3D= ",p_3d.x,p_3d.y,p_3d.z)