Cours Python POO
Cours Python POO
Classes
Python permet le paradigme Programmation Orienté Objet (POO).
vec1 = (3, 4)
vec2 = (1, -3)
def longueur(v):
return math.sqrt(v[0]**2 + v[1]**2)
longueur(v
long1 ec1) =
long2 longueur(v
= ec2)
print(vec1[0]) # Affiche '3'
Classes
Paradigme fonctionnel/procédural :
Données
vec1 = (3, 4)
vec2 = (1,
-3)
Fonctions
def longueur(v):
Classes
Paradigme OO : définir un nouveau type Vecteur pour grouper les
données d'un vecteur et le fonction qui agissent dessus.
Vecteur
x
y
longueur()
Classes
Paradigme OO : définir un nouveau type Vecteur pour grouper les
données d'un vecteur et le fonction qui agissent dessus.
vec1 = Vecteur(3, 4) # création d'un objet Vecteur
vec2 = Vecteur(1, -3) # création d'un objet
Vecteur
ur() =
long1 vec2.longue
long2 ur()
=
vec1.longue
print(vec1.x) # affiche 3
Classes
Paradigme fonctionnel/procédural
chat2
chat1 =
('Felix', ('Cléo',
5) = 7)
def affiche_age(c):
print('{} a {} ans'.format(c[0], c[1]))
affiche_age(chat1)
affiche_age(chat2)
Classes
Paradigme OO :
Chat
= , 7)
chat1 Chat('Felix nom
age
chat2 ', 5) =
Chat('Cléo' affiche_age()
chat1.affiche_age()
print(chat.nom)
Classes
Ces nouveaux types s'appellent classes.
Une nouvelle classe est définie par le mot-clé class.
class NomDeLaClasse:
<instruction 1>
<instruction 2>
.
.
.
<instruction N>
Classes
La définition d'une classe :
class Vecteur:
'''Cette classe représente un
vecteur.''' def __init (self, a, b):
self.x = a
self.y = b
def longueur(self):
return math.sqrt(self.x**2 +
Classes
class Vecteur:
'''Cette classe représente un vecteur.'''
def init s
self.x e
self.y l
f
, :
a =
, a
b = b
)
def longueur(self):
return math.sqrt(self.x**2 + self.y**2)
Classes
class Chat:
'''Cette classe représente un chat.'''
def init (self, n, a):
self.nom = n
self.age = a
def affiche_age(self):
print('{} a {} ans'.format(self.nom,
self.age)) def parle(self):
print('miaou')
monchat = Chat('Felix', 5)
monchat.affiche_age()
monchat.parle()
Classes
Deux syntaxe pour appeler les méthodes :
● objet.methode() syntaxe courante (implicitement transformée dans
la deuxième)
Classe.methode(objet
) ●
class Chat :
def parle(self):
print('miaou')
monchat = Chat()
# Ces deux appels #
monchat.parle() sont équivalents
Chat.parle(monchat)
Classes
Quelques conventions.
●nom des classes : en « CamelCase »
Vecteur
PlanCartesien
Chat
MainWindow
Classes
Les méthodes ont toujours un premier argument qui représente, dans la
méthode, l'objet = l'instance particulière.
Par convention, on l'appelle self.
...
def presente(self):
print('{} a {} ans'.format(self.nom,
self.age)) def parle(self, n):
print('miaou ' * n)
def parle_beaucoup(self):
self.parle(10)
...
Classes
On peut définir des attributs pour les classes aussi (class attributes = attributs de classe),
par affectation.
Ils sont en commun pour toutes les objet crée par la classe.
Souvent utilisés pour les « constantes » du type.
class Cercle:
PI = 3.14159
def init (self, r):
self.rayon = r
def aire(self):
return Cercle.PI * self.rayon ** 2
Classes
Un objet peut être composé par des autres
Rectangle
objets. Exemple : un rectangle est défini par
deux points.
b = Vecteur(5, 4)
class Rectangle:
a = Vecteur(1, 2)
def init (self, p1, x=1
p2): rect = Rectangle(a, y=2
self.p1 = p1 b)
self.p2 = p2 print(rect.aire())
def aire(self): p1 =p2 = aire() Vecteur
largeur = self.p2.x – x=5
self.p1.x hauteur = y=4
self.p2.y – self.p1.y
return largeur *
hauteur Vecteur
Classes
Il n'y a pas d'attributs privés en Python, tout est toujours accessible.
Une convention est de préfixer avec un seule tiret bas les attributs qu'on
veut protéger. Mais c'est juste une « suggestion » aux programmateurs.
class Chat:
def init (self):
self._age = 0
def set_age(self, age):
self._age = max(age, 0)
def get_age(self):
return self._age
Méthodes spéciales et
opérateurs
Méthodes spéciales
On peut utiliser les opérateurs + - * / < > etc... avec des objets. Par exemple,
pour l'operateur + il faut définir une méthode add ()
class Vecteur:
...
def add (self, other):
x = self.x + other.x
y = self.y + other.y
return Vecteur(x, y)
...
>>> v1 = Vecteur(3, 5)
>>> >>> Vecteur(2, -1) v1. add (v2) # v1
v2 v1 + est ‘self’ et v2
= est ‘other’
v2 # équivalent à
Vecteur(5, 4)
Méthodes spéciales
Héritage
Héritage
Création de nouvelles classes à partir de classes déjà définies :
class ClasseDerivee(ClasseDeBase):
<instruction 1>
<instruction 2>
.
.
.
<instruction N>
class A: b = B()
def mA(self): b.mB()
print('A')
mA
B
mB
Héritage
Les classes dérivées peuvent remplacer les méthodes de la classe de
base. class A:
def m(self):
print('A')
B
class B(A): m
def m(self):
print('B')
Héritage
b = B()
b.m() # Affiche “B” class A:
A
m
def f(self):
self.m() f
m
def m(self):
print('A')
B
class B(A): m
def m(self):
print('B')
b = B()
b.f() # Affiche “B”
A
Héritage
Si jamais une méthode de B veut exécuter la méthode originale de A ( chain-up) il faut
utiliser la syntaxe alternative pour appeler les méthodes :
nomclasse.methode(objet)
class A:
def met(self):
print('A')
class B(A):
def met(self):
A.met(self)
print('B')
x = B()
x.met() # Affiche “A” et “B”
Héritage
Alternative : la fonction super()
class A:
def met(self):
print('A')
class B(A):
def met(self):
super().met()
print('B')
x = B()
x.met() # Affiche “A” et “B”
Héritage
On trouve souvent le chain-up dans les méthode d'initialisation :
class A:
def init (self, x):
self.x = x
B(A):
class
def init (self, x):
super().init (x)
self.foo = 'bar'
b = B(5)
Héritage class
Professeur(Personne):
Personne
prenom
nom
def init (self,
class Personne:
prenom, nom, cours):
def init (self, super(). init (prenom,
prenom, nom):
nom) Professeur
self.prenom = prenom cours
self.cours = cours
self.nom = nom Etudiant numero
class
Héritage
class C(A,
C
class A: B): B
bar
multiple pass
foo = 'A'
class B:
A
bar = 'B' foo
print(C.foo, C.bar) # Affiche “A B”
Héritage class B(A): C):
pass
pass
class A: class C:
multiple foo = 'C' print(D.foo)
foo = 'A' class D(B,
Python utilise
l'algorithme «
depth first » :
A on cherche en
foo
profondeur A
foo
dans une
B
branche avant
B
de passer à la
suivante
D
C
D
foo
C
Héritage foo
D→B→A Héritage
multiple →C
pass
multiple class C(A):
Problème avec le « foo = 'C'
diamant »
class D(B, C):
pass
class A: D
foo = 'A' C
print(D.foo) # foo
class B(A): ???
A
foo