0% ont trouvé ce document utile (0 vote)
141 vues174 pages

Programmation Orientée Objet en Python

Le document décrit les concepts de base de la programmation orientée objet en Python, notamment la notion de classe, d'instance, d'attributs et de méthodes. Il présente également des concepts avancés tels que l'héritage, le polymorphisme, les classes abstraites et les itérateurs.

Transféré par

parfait ELABA
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
141 vues174 pages

Programmation Orientée Objet en Python

Le document décrit les concepts de base de la programmation orientée objet en Python, notamment la notion de classe, d'instance, d'attributs et de méthodes. Il présente également des concepts avancés tels que l'héritage, le polymorphisme, les classes abstraites et les itérateurs.

Transféré par

parfait ELABA
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Python : programmation orientée-objet

Achref El Mouelhi

Docteur de l’université d’Aix-Marseille


Chercheur en Programmation par contrainte (IA)
Ingénieur en Génie logiciel

[Link]@[Link]

H & H: Research and Training 1 / 117


Plan

1 Introduction

2 Classe
str ()
repr ()
init ()
Setter
Getter
property()
Deleter
@property
del ()
Attributs et méthodes statiques

H & H: Research and Training 2 / 117


Plan

3 Héritage
Héritage simple
Héritage multiple

4 Polymorphisme
Surcharge
Redéfinition

5 Classe et méthode abstraites

6 Indexeur
getitem ()
setitem ()
len ()

H & H: Research and Training 3 / 117


Plan

7 Itérateur

8 Opérateur
eq ()
gt ()
add ()

9 Généricité

10 Énumération

11 Introspection

12 Conventions

H & H: Research and Training 4 / 117


Introduction

Python
Qu’est ce qu’une classe en POO ?

Ça correspond à un plan, un moule, une usine...


C’est une description abstraite d’un type d’objets
I c
E
Elle représente un ensemble d’objets ayant lesH
L mêmes propriétés
statiques (attributs) et dynamiques O U
L M (méthodes)
h r e fE
A c
c

H & H: Research and Training 5 / 117


Introduction

Python
Qu’est ce qu’une classe en POO ?

Ça correspond à un plan, un moule, une usine...


C’est une description abstraite d’un type d’objets
I c
E
Elle représente un ensemble d’objets ayant lesH
L mêmes propriétés
statiques (attributs) et dynamiques O U
L M (méthodes)
r e E
f d’instance
Qu’est ce que c’est lah
A c notion ?
c correspond à un objet créé à partir d’une classe (via
Une instance
le constructeur)

H & H: Research and Training 5 / 117


Introduction

Python
Qu’est ce qu’une classe en POO ?

Ça correspond à un plan, un moule, une usine...


C’est une description abstraite d’un type d’objets
I c
E
Elle représente un ensemble d’objets ayant lesH
L mêmes propriétés
statiques (attributs) et dynamiques O U
L M (méthodes)
r e E
f d’instance
Qu’est ce que c’est lah
A c notion ?
c correspond à un objet créé à partir d’une classe (via
Une instance
le constructeur)
L’instanciation : création d’un objet d’une classe

H & H: Research and Training 5 / 117


Introduction

Python
Qu’est ce qu’une classe en POO ?

Ça correspond à un plan, un moule, une usine...


C’est une description abstraite d’un type d’objets
I c
E
Elle représente un ensemble d’objets ayant lesH
L mêmes propriétés
statiques (attributs) et dynamiques O U
L M (méthodes)
r e E
f d’instance
Qu’est ce que c’est lah
A c notion ?
c correspond à un objet créé à partir d’une classe (via
Une instance
le constructeur)
L’instanciation : création d’un objet d’une classe
instance ≡ objet

H & H: Research and Training 5 / 117


Introduction

Python

De quoi est composé une classe ?

NomClasse

I c

les attributs
ELH
U
L MO
r e f E
les méthodes

ch
c A

Attribut : [visibilité] + type + nom
Méthode : [visibilité] + valeur de retour + nom + arguments ≡
signature : exactement comme les fonctions en procédurale

H & H: Research and Training 6 / 117


Classe

Python

Particularité de Python I c
H
EL classe mère
U
Toutes les classes héritent implicitement d’une
Object.
L MO
r e E désigner l’objet courant.
f de
A c h
Le mot-clé self permet

H & H: Research and Training 7 / 117


Classe

Python

I c
Démarche
E L H
U
MO
Utilisez PyCharm pour créer un nouveau projet cours-poo dans
votre espace de travail L
f Ede créer un fichier [Link]
c h
Cochez la case qui r e
permet

c A

H & H: Research and Training 8 / 117


Classe

Python
Considérons la classe Personne définie dans [Link]
class Personne:
pass

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 9 / 117


Classe

Python
Considérons la classe Personne définie dans [Link]
class Personne:
pass

I c

Dans [Link], instancions la classe Personne
ELH
U
MO
p = Personne()

f E L
chre
c A

H & H: Research and Training 9 / 117


Classe

Python
Considérons la classe Personne définie dans [Link]
class Personne:
pass

I c

Dans [Link], instancions la classe Personne
ELH
U
MO
p = Personne()

f E L
chre
N’oublions d’importer la classe Personne

c A

from personne import Personne

H & H: Research and Training 9 / 117


Classe

Python
Considérons la classe Personne définie dans [Link]
class Personne:
pass

I c

Dans [Link], instancions la classe Personne
ELH
U
MO
p = Personne()

f E L
chre
N’oublions d’importer la classe Personne

c A

from personne import Personne

Et si on affiche l’instance
print(p)
# affiche <[Link] object at 0x00D28160>

H & H: Research and Training 9 / 117


Classe

Python
Dans une classe, on peut déclarer des attributs (et les initialiser)
class Personne:
num: int
nom: str
prenom: str

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 10 / 117


Classe

Python
Dans une classe, on peut déclarer des attributs (et les initialiser)
class Personne:
num: int
nom: str
prenom: str

I c

ELH
U
MO
Pour affecter des valeurs aux différents attributs
from personne import Personne
f E L
p = Personne()
chre
c A
[Link] = 100
[Link] = ’wick’
[Link] = "john"

H & H: Research and Training 10 / 117


Classe

Python
Dans une classe, on peut déclarer des attributs (et les initialiser)
class Personne:
num: int
nom: str
prenom: str

I c

ELH
U
MO
Pour affecter des valeurs aux différents attributs
from personne import Personne
f E L
p = Personne()
chre
c A
[Link] = 100
[Link] = ’wick’
[Link] = "john"

Pour afficher la valeur d’un attribut


print([Link])
# affiche wick
H & H: Research and Training 10 / 117
Classe str ()

Python
Explication

Pour afficher les détails d’un objet, il faut que la méthode str (self) soit implémentée

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 11 / 117


Classe str ()

Python
Explication

Pour afficher les détails d’un objet, il faut que la méthode str (self) soit implémentée

I c

Définissons la méthode str ()
ELH
U
class Personne:
num: int
L MO
f E
hre
nom: str
prenom: str
c
c A
def __str__(self) -> str:

return [Link] + " " + [Link]

H & H: Research and Training 11 / 117


Classe str ()

Python
Explication

Pour afficher les détails d’un objet, il faut que la méthode str (self) soit implémentée

I c

Définissons la méthode str ()
ELH
U
class Personne:
num: int
L MO
f E
hre
nom: str
prenom: str
c
c A
def __str__(self) -> str:

return [Link] + " " + [Link]

Dans [Link], affichons les détails de notre instance p

print(p)
# affiche john wick

H & H: Research and Training 11 / 117


Classe repr ()

Python

Remplaçons la méthode str () par repr ()


class Personne:
num: int
I c

nom: str
ELH
prenom: str
U
def __repr__(self) -> str:
L MO
E
return [Link] + " " + [Link]
f
chre
c A

H & H: Research and Training 12 / 117


Classe repr ()

Python

Remplaçons la méthode str () par repr ()


class Personne:
num: int
I c

nom: str
ELH
prenom: str
U
def __repr__(self) -> str:
L MO
E
return [Link] + " " + [Link]
f
A c hre
c
Exécutons le [Link] précédent sans le changer
print(p)
# affiche john wick

H & H: Research and Training 12 / 117


Classe repr ()

Python

Ajoutons la méthode str ()

class Personne:
num: int
nom: str
prenom: str
I c

ELH
def __str__(self) -> str:
U
MO
return "prénom : " + [Link] + " " + "nom : " + [Link]

L
def __repr__(self) -> str:
f E
hre
return [Link] + " " + [Link]
c
c A

H & H: Research and Training 13 / 117


Classe repr ()

Python

Ajoutons la méthode str ()

class Personne:
num: int
nom: str
prenom: str
I c

ELH
def __str__(self) -> str:
U
MO
return "prénom : " + [Link] + " " + "nom : " + [Link]

L
def __repr__(self) -> str:
f E
hre
return [Link] + " " + [Link]
c
c A

Exécutons le [Link] précédent sans le changer

print(p)
# affiche prénom : john nom : wick

H & H: Research and Training 13 / 117


Classe repr ()

Python

Testons avec les chaı̂nes formatées


from personne import Personne

I c

p = Personne()
[Link] = 100 ELH
U
[Link] = ’wick’
L MO
[Link] = "john"
f E
chre
print(f"{p}")
c A

# prénom : john nom : wick

print(f"{p!r}")
# john wick

H & H: Research and Training 14 / 117


Classe repr ()

Python

Convention sur str () et repr ()


I c

Utilisez str () pour un affichage client L
E H
O U
M (phase de développement)
Utilisez repr () pour le débogage
L
r e E
la fdocumentation officielle :
A c h
Plus de détails dans
[Link]
c
[Link]#object. repr

H & H: Research and Training 15 / 117


Classe init ()

Python
Remarques

Par défaut, toute classe en Python a un constructeur par défaut


sans paramètre

I c

H
Pour simplifier la création d’objets, on peut définir un nouveau
EL
U
constructeur qui prend en paramètre plusieurs attributs de la
classe
L MO
f E
chre
c A

H & H: Research and Training 16 / 117


Classe init ()

Python
Remarques

Par défaut, toute classe en Python a un constructeur par défaut


sans paramètre

I c

H
Pour simplifier la création d’objets, on peut définir un nouveau
EL
U
constructeur qui prend en paramètre plusieurs attributs de la
classe
L MO
f E
A c hre
c
avec Python
Les constructeurs

On le déclare avec le mot-clé init ()


Il peut contenir la visibilité des attributs si on veut simplifier la
déclaration

H & H: Research and Training 16 / 117


Classe init ()

Python
Le constructeur de la classe Personne acceptant trois paramètres
class Personne:
def __init__(self, num: int, nom: str, prenom: str):
[Link] = num
[Link] = nom
[Link] = prenom
def __str__(self) -> str:
I c

return [Link] + " " + [Link]
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 17 / 117


Classe init ()

Python
Le constructeur de la classe Personne acceptant trois paramètres
class Personne:
def __init__(self, num: int, nom: str, prenom: str):
[Link] = num
[Link] = nom
[Link] = prenom
def __str__(self) -> str:
I c

return [Link] + " " + [Link]
ELH
U
L MO
f E
En testant le main précédent, une erreur sera générée
from personne import Personne
chre
p = Personne()
[Link] = 100
c A

[Link] = ’wick’
[Link] = "john"

print(p)
# affiche TypeError: __init__() missing 3 required positional arguments
: ’num’, ’nom’, and ’prenom’

H & H: Research and Training 17 / 117


Classe init ()

Python

Explication

c

Le constructeur par défaut a été écrasé (il n’existe plus)
I
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 18 / 117


Classe init ()

Python

Explication

c

Le constructeur par défaut a été écrasé (il n’existe plus)
I
ELH
U
L MO
f E
hre
Comment faire ?
c
surcharge)
c A
Python n’autorise pas la présence de plusieurs constructeurs (la

On peut utiliser les valeurs par défaut

H & H: Research and Training 18 / 117


Classe init ()

Python

Le nouveau constructeur avec les valeurs par défaut


class Personne:
I c

H
def __init__(self, num: int = 0,Lnom: str = ’’,
prenom: str = ’’): O UE
[Link] = num L M
[Link] =re
h fE
nom
A c = prenom
[Link]
c
def __str__(self) -> str:
return [Link] + " " + [Link]

H & H: Research and Training 19 / 117


Classe init ()

Python

Pour tester les deux constructeurs


from personne import Personne

I c

p = Personne()
ELH
[Link] = 100
U
[Link] = ’wick’
L MO
[Link] = "john"
f E
chre
c A

p2 = Personne(100, ’wick’, ’john’)

print(p2)
# affiche john wick

H & H: Research and Training 20 / 117


Classe Setter

Python

Hypothèse

Supposant que l’on n’accepte pas de valeur négative pour l’attribut


num de la classe Personne
I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 21 / 117


Classe Setter

Python

Hypothèse

Supposant que l’on n’accepte pas de valeur négative pour l’attribut


num de la classe Personne
I c

ELH
U
L MO
f E
Démarche
chre
1
c A

Bloquer l’accès direct aux attributs (mettre la visibilité à private)
2 Définir des méthodes qui contrôlent l’affectation de valeurs aux
attributs (les setter)

H & H: Research and Training 21 / 117


Classe Setter

Python

Particularité de Python
I c
Le mot-clé private n’existe pas
EL H
On préfixe les attributs par deuxM O U
underscores pour indiquer qu’ils
sont privés
fE L
h r e
cattributs par un underscore pour indiquer qu’ils sont
protég c
és
A
On préfixe les

H & H: Research and Training 22 / 117


Classe Setter

Ajoutons deux underscrores à tous les attributs et définissons un setter pour chaque
attribut

class Personne:

def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
self.__num = num
self.__nom = nom
self.__prenom = prenom
I c

def set_num(self, num: int) -> None:
ELH
U
MO
if num > 0:
self.__num = num
else:
f E L
hre
self.__num = 0
c
c A

def set_nom(self, nom: str) -> None:
self.__nom = nom

def set_prenom(self, prenom: str) -> None:


self.__prenom = prenom

def __str__(self) -> str:


return str(self.__num) + " " + self.__prenom + " " + self.__nom

H & H: Research and Training 23 / 117


Classe Setter

Python

Pour tester dans [Link]


from personne import Personne

I c

p = Personne(100, ’wick’, ’john’)
ELH
U
print(p)
L MO
# affiche 100 john wick
f E
chre
p.set_num(-100) c A

print(p)
# affiche 0 john wick

H & H: Research and Training 24 / 117


Classe Setter

Python

Cependant, le constructeur accepte toujours les valeurs


négatives
from personne import Personne
I c

p = Personne(-100, ’wick’, ’john’) LH
O UE
L M
print(p)
f E
rewick
h
# affiche -100 john
c
c A
p.set_num(-100)

print(p)
# affiche 0 john wick

H & H: Research and Training 25 / 117


Classe Setter

Pour résoudre le problème précédent, on appelle le setter dans le constructeur

class Personne:

def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
self.set_num(num)
self.__nom = nom
self.__prenom = prenom
I c

def set_num(self, num: int) -> None:
ELH
if num > 0:
U
self.__num = num
else:
L MO
f E
hre
self.__num = 0

c
c A
def set_nom(self, nom: str) -> None:


self.__nom = nom

def set_prenom(self, prenom: str) -> None:


self.__prenom = prenom

def __str__(self) -> str:


return str(self.__num) + " " + self.__prenom + " " + self.__nom

H & H: Research and Training 26 / 117


Classe Setter

Python

Les valeurs négatives ne passent plus par le constructeur ni par


le setter
from personne import Personne
I c

p = Personne(-100, ’wick’, ’john’) LH
O UE
L M
print(p)
ref E
h
# affiche 0 john wick
c
c A
p.set_num(-100)

print(p)
# affiche 0 john wick

H & H: Research and Training 27 / 117


Classe Getter

Python

Question

I c

Comment récupérer les attributs (privés) de la classe Personne ?
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 28 / 117


Classe Getter

Python

Question

I c

Comment récupérer les attributs (privés) de la classe Personne ?
ELH
U
L MO
f E
Démarche
chre
c A

Définir des méthodes qui retournent les valeurs des attributs (les
getter)

H & H: Research and Training 28 / 117


Classe Getter

Ajoutons les getters dans la classe Personne

class Personne:

def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
self.set_num(num)
self.__nom = nom
self.__prenom = prenom

def get_num(self) -> int:


return self.__num

I c

def set_num(self, num: int) -> None:
if num > 0:
ELH
self.__num = num
U
MO
else:

L
self.__num = 0

f E
hre
def get_nom(self) -> str:
return self.__nom

c
c A
def set_nom(self, nom: str) -> None:


self.__nom = nom

def get_prenom(self) -> str:


return self.__prenom

def set_prenom(self, prenom: str) -> None:


self.__prenom = prenom

def __str__(self) -> str:


return str(self.__num) + " " + self.__prenom + " " + self.__nom

H & H: Research and Training 29 / 117


Classe Getter

Python

Pour tester
I c

from personne import Personne
EL H
U
L MO
p = Personne(100, ’wick’, ’john’)

h r e fE
A
# affichec100
c
print(p.get_num(), p.get_nom(), p.get_prenom())
wick john

H & H: Research and Training 30 / 117


Classe property()

Python

I c

La méthode property() permet
ELH
U
d’indiquer les setter et getter
L MO
f E
hre
de les utiliser comme un attribut
c
c A

H & H: Research and Training 31 / 117


Classe property()

Python
Ajoutons property dans la classe Personne

class Personne:
def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
[Link] = num
self.__nom = nom
self.__prenom = prenom

def get_num(self) -> int:

I c

return self.__num
def set_num(self, num: int) -> None:

ELH
U
if num > 0:

MO
self.__num = num
else:
self.__num = 0

f
num = property(get_num, set_num)
E L
def get_nom(self) -> str:
c hre
c A
return self.__nom


def set_nom(self, nom: str) -> None:
self.__nom = nom
nom = property(get_nom, set_nom)

def get_prenom(self) -> str:


return self.__prenom
def set_prenom(self, prenom: str) -> None:
self.__prenom = prenom
prenom = property(get_prenom, set_prenom)

def __str__(self) -> str:


return str(self.__num) + " " + self.__prenom + " " + self.__nom

H & H: Research and Training 32 / 117


Classe property()

Python

Pour tester
from personne import Personne
p = Personne(100, ’wick’, ’john’)
I c

ELH
U
print(p)
L MO
# affiche 100 john wick
f E
chre
c A
[Link] = -100

print([Link], [Link], [Link])
# affiche 0 wick john

H & H: Research and Training 33 / 117


Classe Deleter

Python

I c

Le deleter permet
E LH
de supprimer un attribut d’un objet O U
L M
ref
de ne plus avoir accès à E
un attribut
c h
c A

H & H: Research and Training 34 / 117


Classe Deleter

Python

Définissons le deleter pour l’attribut prenom de la classe


Personne
def get_prenom(self) -> str:
I c

return self.__prenom
E LH
U
= L
self.__prenom E
MO str) -> None:
def set_prenom(self, prenom:
prenom

c h ref
c A
def del_prenom(self) -> None:
del self.__prenom

prenom = property(get_prenom, set_prenom,


del_prenom)

H & H: Research and Training 35 / 117


Classe Deleter

Python

Pour tester
from personne import Personne

I c

p = Personne(100, ’wick’, ’john’)
ELH
U
print(p)
L MO
# affiche 100 wick john
f E
chre
del [Link]
c A

print(p)
# affiche AttributeError: ’Personne’ object has no
attribute ’__prenom’

H & H: Research and Training 36 / 117


Classe @property

Python

Le décorateur (annotation) property() permet

de simplifier la déclaration des getters et setters

I c

de ne pas déclarer les getter et setter avec dans property()

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 37 / 117


Classe @property

Python

Le décorateur (annotation) property() permet

de simplifier la déclaration des getters et setters

I c

de ne pas déclarer les getter et setter avec dans property()

ELH
U
L MO
f E
hre
Pour générer les propriétés avec PyCharm
c
c A

saisissez prop
choisissez si vous voulez le getter, getter et setter, getter, setter et
deleter
validez en cliquant sur entrée

H & H: Research and Training 37 / 117


Classe @property
Modifions la classe Personne et utilisons les décorateurs

class Personne:
def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
[Link] = num
self.__nom = nom
self.__prenom = prenom

@property
def num(self) -> int:
return self.__num
@[Link]

I c

H
def num(self, num) -> None:

EL
if num > 0:
self.__num = num

U
MO
else:
self.__num = 0
@property
def nom(self) -> str:
f E L
hre
return self.__nom
@[Link]

c
c A
def nom(self, nom) -> None:
self.__nom = nom
@property

def prenom(self) -> str:
return self.__prenom
@[Link]
def prenom(self, prenom) -> None:
self.__prenom = prenom
@[Link]
def prenom(self) -> str:
del self.__prenom
def __str__(self) -> str:
return str(self.__num) + " " + self.__prenom + " " + self.__nom

H & H: Research and Training 38 / 117


Classe @property

Python

Pour tester
from personne import Personne

I c

p = Personne(100, ’wick’, ’john’)
ELH
U
print(p)
L MO
f E
hre
# affiche 100 john wick
c
[Link] = -100 c A

print([Link], [Link], [Link])
# affiche 0 wick john

H & H: Research and Training 39 / 117


Classe del ()

Python

I c
del ()
EL H
O
destructeur : exécuté à la destruction de U l’objet
L M
f Eclé dell’objet n’est plus référencé) ou
peut être implicitement (lorsque
r e
A ch
explicitement avec le mot

H & H: Research and Training 40 / 117


Classe del ()

Python

Ajoutons le destructeur dans la classe Personne


class Personne:

I c

def __init__(self, num: int = 0, nom: str = ’’,
prenom: str = ’’):
ELH
U
[Link] = num
L MO
f E
hre
self._nom = nom
A c
self._prenom = prenom
c
def __del__(self):
print("destructeur appelé")

# + le contenu précédent

H & H: Research and Training 41 / 117


Classe del ()

Python

Pour tester dans le main


from personne import Personne
I c

p = Personne(100, ’wick’, ’john’) EL
H
M OU
print(p)
f E L
c h
# affiche 100 johnrewick
del p c A
# affiche destructeur appelé

H & H: Research and Training 42 / 117


Classe del ()

Python

Le destructeur sera appelé implicitement si l’objet n’est plus


référencé
from personne import Personne
I c

ELH
U
p = Personne(100, ’wick’, ’john’)

L MO
print(p)
h r e fE
A c
# affiche 100 john wick
c
print("fin du programme")
# affiche fin du programme
# destructeur appelé

H & H: Research and Training 43 / 117


Classe Attributs et méthodes statiques

Python

Récapitulatif

Les instances d’une même classe ont toutes les mêmes attributs mais pas les mêmes
valeurs

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 44 / 117


Classe Attributs et méthodes statiques

Python

Récapitulatif

Les instances d’une même classe ont toutes les mêmes attributs mais pas les mêmes
valeurs

I c

ELH
U
Hypothèse
L MO
f E
hre
Et si nous voulions qu’un attribut ait une valeur partagée par toutes les instances (par
c
exemple, le nombre d’objets instanciés de la classe Personne)

c A

H & H: Research and Training 44 / 117


Classe Attributs et méthodes statiques

Python

Récapitulatif

Les instances d’une même classe ont toutes les mêmes attributs mais pas les mêmes
valeurs

I c

ELH
U
Hypothèse
L MO
f E
hre
Et si nous voulions qu’un attribut ait une valeur partagée par toutes les instances (par
c
exemple, le nombre d’objets instanciés de la classe Personne)

c A

Solution : attribut statique ou attribut de classe

Un attribut dont la valeur est partagée par toutes les instances de la classe.

H & H: Research and Training 44 / 117


Classe Attributs et méthodes statiques

Python

Exemple

Si on voulait créer un attribut contenant le nombre d’objets créés à partir de la classe


Personne

I c

Notre attribut doit être déclaré static, sinon chaque objet pourrait avoir sa propre valeur
pour cet attribut
ELH
U
MO
En Python, un attribut qui n’est pas déclaré dans le constructeur est un attribut static
L
f E
chre
c A

H & H: Research and Training 45 / 117


Classe Attributs et méthodes statiques

Python

Exemple

Si on voulait créer un attribut contenant le nombre d’objets créés à partir de la classe


Personne

I c

Notre attribut doit être déclaré static, sinon chaque objet pourrait avoir sa propre valeur
pour cet attribut
ELH
U
MO
En Python, un attribut qui n’est pas déclaré dans le constructeur est un attribut static
L
f E
chre
c A

Particularité de Python

Un attribut qui n’est pas déclaré dans le constructeur est un attribut statique

Pas de mot-clé static comme dans la plupart des LOO

H & H: Research and Training 45 / 117


Classe Attributs et méthodes statiques

Python
Ajoutons un attribut statique nbr personnes à la liste d’attributs de la classe Personne

nbr_personnes = 0

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 46 / 117


Classe Attributs et méthodes statiques

Python
Ajoutons un attribut statique nbr personnes à la liste d’attributs de la classe Personne

nbr_personnes = 0

I c

H
Incrémentons notre compteur de personnes dans le constructeur

EL
U
def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
[Link] = num
L MO
self.__nom = nom
f E
hre
self.__prenom = prenom

c
Personne.nbr_personnes += 1

c A

H & H: Research and Training 46 / 117


Classe Attributs et méthodes statiques

Python
Ajoutons un attribut statique nbr personnes à la liste d’attributs de la classe Personne

nbr_personnes = 0

I c

H
Incrémentons notre compteur de personnes dans le constructeur

EL
U
def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’):
[Link] = num
L MO
self.__nom = nom
f E
hre
self.__prenom = prenom

c
Personne.nbr_personnes += 1

c A

Décrémentons dans le destructeur

def __del__(self):
Personne.nbr_personnes -= 1
print("destructeur appelé")

H & H: Research and Training 46 / 117


Classe Attributs et méthodes statiques

Python

Testons cela dans [Link]


from personne import Personne
I c

ELH
print(Personne.nbr_personnes)
U
# affiche 0
L MO
h r e f E ’john’)
A c
p = Personne(100, ’wick’,

c
print(Personne.nbr_personnes)
# affiche 1

H & H: Research and Training 47 / 117


Classe Attributs et méthodes statiques

Python

I c

ELH
Pour définir une méthode statique, on utilise

soit le décorateur staticmethod O


U
L M
ref E
soit le décorateur classmethod
c h
c A

H & H: Research and Training 48 / 117


Classe Attributs et méthodes statiques

Python

Définissons une méthode statique avec le décorateur (@staticmethod)


pour incrémenter nbr personnes
@staticmethod
def increment() -> None:
I c

Personne.nbr_personnes += 1
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 49 / 117


Classe Attributs et méthodes statiques

Python

Définissons une méthode statique avec le décorateur (@staticmethod)


pour incrémenter nbr personnes
@staticmethod
def increment() -> None:
I c

Personne.nbr_personnes += 1
ELH
U
L MO
f E
hre
Et l’utiliser dans le constructeur
c
str = ’’): c A
def __init__(self, num: int = 0, nom: str = ’’, prenom:

[Link] = num
self.__nom = nom
self.__prenom = prenom
[Link]()

H & H: Research and Training 49 / 117


Classe Attributs et méthodes statiques

Python

Testons cela dans [Link]


from personne import Personne
I c

ELH
print(Personne.nbr_personnes)
U
# affiche 0
L MO
h r e f E ’john’)
A c
p = Personne(100, ’wick’,

c
print(Personne.nbr_personnes)
# affiche 1

H & H: Research and Training 50 / 117


Classe Attributs et méthodes statiques

Python

On peut aussi définir une méthode statique avec le décorateur


(@classmethod) et pour incrémenter nbr personnes on injecte cls
@classmethod
def increment(cls) -> None:
I c

cls.nbr_personnes += 1
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 51 / 117


Classe Attributs et méthodes statiques

Python

On peut aussi définir une méthode statique avec le décorateur


(@classmethod) et pour incrémenter nbr personnes on injecte cls
@classmethod
def increment(cls) -> None:
I c

cls.nbr_personnes += 1
ELH
U
L MO
f E
hre
Rien à modifier dans le constructeur
c
str = ’’): c A
def __init__(self, num: int = 0, nom: str = ’’, prenom:

[Link] = num
self.__nom = nom
self.__prenom = prenom
[Link]()

H & H: Research and Training 51 / 117


Classe Attributs et méthodes statiques

Python

Pour tester, rien à modifier dans [Link]


from personne import Personne
I c

ELH
print(Personne.nbr_personnes)
U
# affiche 0
L MO
h r e f E ’john’)
A c
p = Personne(100, ’wick’,

c
print(Personne.nbr_personnes)
# affiche 1

H & H: Research and Training 52 / 117


Classe Attributs et méthodes statiques

Python

Pour conclure
I c

H
Une méthode d’instance reçoit le mot-clé self comme premier
EL
paramètre
O U
L
Une méthode de classe reçoit leMmot-clé cls comme premier
paramètre
h r e fE
A c
c
Une méthode
paramètre.
static ne reçoit ni self ni cls comme premier

H & H: Research and Training 53 / 117


Classe Attributs et méthodes statiques

Python
Exercice
Définissez une classe Adresse avec trois attributs privés rue,
code postal et ville de type chaı̂ne de caractère

I c
setters EL H
Définissez un constructeur avec trois paramètres, les getters et
U
Oattribut adresse (de type
L Mun
Dans la classe Personne, ajouter
r e f E et générez les getter et setter de
Adresse) dans le constructeur
h
A c
ce nouvel attribut
c
Dans [Link], créez deux objets : un objet personne (de type
Personne) et adresse (de type Adresse) et affectez le à l’objet
personne
Affichez tous les attributs de l’objet personne

H & H: Research and Training 54 / 117


Héritage

Python

L’héritage, quand ?

I c
Lorsque deux ou plusieurs classes partagent plusieurs attributs

(et méthodes)
EL H
U
L MO
Lorsqu’une Classe1 est une [sorte de] Classe2

h r e fE
A c
c

H & H: Research and Training 55 / 117


Héritage

Python

L’héritage, quand ?

I c
Lorsque deux ou plusieurs classes partagent plusieurs attributs

(et méthodes)
EL H
U
L MO
Lorsqu’une Classe1 est une [sorte de] Classe2

h r e fE
c
c A
Forme gén
érale
class ClasseFille (ClasseMère):
# code

H & H: Research and Training 55 / 117


Héritage Héritage simple

Python
Exemple

Un enseignant a un numéro, un nom, un prénom, un genre et un salaire

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 56 / 117


Héritage Héritage simple

Python
Exemple

Un enseignant a un numéro, un nom, un prénom, un genre et un salaire

c

Un étudiant a aussi un numéro, un nom, un prénom, un genre et un
I
niveau
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 56 / 117


Héritage Héritage simple

Python
Exemple

Un enseignant a un numéro, un nom, un prénom, un genre et un salaire

c

Un étudiant a aussi un numéro, un nom, un prénom, un genre et un
I
niveau
E LH
U
MOsont une sorte de personne
Sémantiquement, enseignant et étudiant
L
h r e fE
A c
c

H & H: Research and Training 56 / 117


Héritage Héritage simple

Python
Exemple

Un enseignant a un numéro, un nom, un prénom, un genre et un salaire

c
Un étudiant a aussi un numéro, un nom, un prénom, un genre et un
I
niveau
E L H
U
MOsont une sorte de personne
Sémantiquement, enseignant et étudiant
L
r e fE
En plus, les deux partagent
h plusieurs attributs tels que numéro, nom,
c
c A
prénom et genre

H & H: Research and Training 56 / 117


Héritage Héritage simple

Python
Exemple

Un enseignant a un numéro, un nom, un prénom, un genre et un salaire

c
Un étudiant a aussi un numéro, un nom, un prénom, un genre et un
I
niveau
E L H
U
MOsont une sorte de personne
Sémantiquement, enseignant et étudiant
L
r e fE
En plus, les deux partagent
h plusieurs attributs tels que numéro, nom,
c
c A
prénom et genre

Donc, on peut peut utiliser la classe Personne puisqu’elle contient tous
les attributs numéro, nom, prénom et genre

H & H: Research and Training 56 / 117


Héritage Héritage simple

Python
Exemple

Un enseignant a un numéro, un nom, un prénom, un genre et un salaire

c
Un étudiant a aussi un numéro, un nom, un prénom, un genre et un
I
niveau
E L H
U
MOsont une sorte de personne
Sémantiquement, enseignant et étudiant
L
r e fE
En plus, les deux partagent
h plusieurs attributs tels que numéro, nom,
c
c A
prénom et genre

Donc, on peut peut utiliser la classe Personne puisqu’elle contient tous
les attributs numéro, nom, prénom et genre

Les classes Étudiant et Enseignant hériteront donc de la classe


Personne

H & H: Research and Training 56 / 117


Héritage Héritage simple

Contenu de [Link]

from personne import Personne

class Etudiant(Personne):

def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’,
niveau: str = ’’):
super().__init__(num, nom, prenom)
I c

self.__niveau = niveau

ELH
U
MO
@property
def niveau(self) -> str:
return self.__niveau
f E L
hre
@[Link]

c
def niveau(self, niveau) -> None:

c A
self.__niveau = niveau

H & H: Research and Training 57 / 117


Héritage Héritage simple

Contenu de [Link]

from personne import Personne

class Etudiant(Personne):

def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’,
niveau: str = ’’):
super().__init__(num, nom, prenom)
I c

self.__niveau = niveau

ELH
U
MO
@property
def niveau(self) -> str:
return self.__niveau
f E L
hre
@[Link]

c
def niveau(self, niveau) -> None:

c A
self.__niveau = niveau

Remarques

class A (B): permet d’indiquer que la classe A hérite de la classe B

super (): permet d’appeler une méthode de la classe mère

H & H: Research and Training 57 / 117


Héritage Héritage simple

Python
Contenu de [Link]
from personne import Personne

class Enseignant(Personne):
I c

H
L str = ’’,
prenom: str = ’’, salaire:O UE
def __init__(self, num: int = 0, nom:
int = 0):
super().__init__(num, M
self.__salairef=E
L nom, prenom)
c h re salaire

c A
@property
def salaire(self) -> int:
return self.__salaire
@[Link]
def salaire(self, salaire) -> None:
self.__salaire = salaire

H & H: Research and Training 58 / 117


Héritage Héritage simple

Python
Pour créer deux objets Enseignant et Etudiant dans [Link]
from etudiant import Etudiant
from enseignant import Enseignant

etudiant = Etudiant(200, ’maggio’, ’toni’, "licence") I c



print(etudiant)
ELH
U
MO
# affiche 200 toni maggio

f E L
hre
enseignant = Enseignant(300, ’dalton’, ’jack’, 1700)
print(enseignant)
c
c A

# affiche 300 jack dalton

H & H: Research and Training 59 / 117


Héritage Héritage simple

Python
Pour créer deux objets Enseignant et Etudiant dans [Link]
from etudiant import Etudiant
from enseignant import Enseignant

etudiant = Etudiant(200, ’maggio’, ’toni’, "licence") I c



print(etudiant)
ELH
U
MO
# affiche 200 toni maggio

f E L
hre
enseignant = Enseignant(300, ’dalton’, ’jack’, 1700)
print(enseignant)
c
c A

# affiche 300 jack dalton

Remarque

Le salaire et le niveau ne sont pas affichés.

H & H: Research and Training 59 / 117


Héritage Héritage simple

Python

Redéfinissons str dans [Link]


def __str__(self):
return super().__str__() + " " + self.
I c

__niveau
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 60 / 117


Héritage Héritage simple

Python

Redéfinissons str dans [Link]


def __str__(self):
return super().__str__() + " " + self.
I c

__niveau
ELH
U
L MO
re f E
h
Et dans [Link]
c
def c A
__str__(self):
return super().__str__() + " " + str(self.
__salaire)

H & H: Research and Training 60 / 117


Héritage Héritage simple

Python

Re-testons tout cela dans [Link]


from etudiant import Etudiant
from enseignant import Enseignant I c

H
EL "licence")
etudiant = Etudiant(200, ’maggio’, U
MO
’toni’,
print(etudiant)
L
f Elicence
c h r e
# affiche 200 toni maggio

c
A
enseignant = Enseignant(300, ’dalton’, ’jack’, 1700)
print(enseignant)
# affiche 300 jack dalton 1700

H & H: Research and Training 61 / 117


Héritage Héritage simple

Python

Remarques

c
super(Etudiant, self) est une écriture Python simplifiée et
I
remplacée en Python 3 par super().
E L H
U
O ou Enseignant par
En remplaçant super() dans Etudiant
L leM
h r e fE
Personne, le résultat restera même.

A c
super() est conseill é pour appeler les méthodes de la classe
cniveau suivant tant dis que Personne (ou le nom d’une
mère du
classe mère d’un niveau quelconque) permet de préciser le
niveau de la classe mère qu’on cherche à appeler.

H & H: Research and Training 62 / 117


Héritage Héritage simple

TypeScript

Remarque

Pour connaı̂tre la classe d’un objet, on peut utiliser le mot-clé isinstance

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 63 / 117


Héritage Héritage simple

TypeScript

Remarque

Pour connaı̂tre la classe d’un objet, on peut utiliser le mot-clé isinstance

I c

ELH
U
MO
Exemple

f E L
print(isinstance(enseignant, Enseignant))
# affiche True
chre
c A

print(isinstance(enseignant, Personne))
# affiche True

print(isinstance(p, Enseignant))
# affiche False

H & H: Research and Training 63 / 117


Héritage Héritage simple

Exercice

1 Créer un objet de type Etudiant, un deuxième de type Enseignant et un dernier de


type Personne stocker les tous dans un seul tableau.

2 Parcourir le tableau et afficher pour chacun soit le numero s’il est personne, soit le
salaire s’il est enseignant ou soit le niveau s’il est étudiant.

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 64 / 117


Héritage Héritage simple

Exercice

1 Créer un objet de type Etudiant, un deuxième de type Enseignant et un dernier de


type Personne stocker les tous dans un seul tableau.

2 Parcourir le tableau et afficher pour chacun soit le numero s’il est personne, soit le
salaire s’il est enseignant ou soit le niveau s’il est étudiant.

I c

ELH
U
MO
Pour parcourir un tableau, on peut faire
from personne import Personne
f E L
hre
from etudiant import Etudiant

c
from enseignant import Enseignant

c A

p = Personne(100, ’wick’, ’john’)
etudiant = Etudiant(200, ’maggio’, ’toni’, "licence")
enseignant = Enseignant(300, ’dalton’, ’jack’, 1700)

list = [p, etudiant, enseignant]

for elt in list:


pass

H & H: Research and Training 64 / 117


Héritage Héritage simple

Python

Solution

I c

for elt in list:
if isinstance(elt, Etudiant): ELH
U
print([Link])
L MO
elif isinstance(elt, Enseignant):
f E
print([Link])
chre
else:
c A

print([Link])

H & H: Research and Training 65 / 117


Héritage Héritage multiple

Python

Particularité du Python
I c

Héritage multiple : une classe peut hériterE
H
L ément de
simultan
U
plusieurs autres
L MO
r e
L’héritage multiple est
h f E é par certains langages comme
autoris
Python, C++...c
c A

H & H: Research and Training 66 / 117


Héritage Héritage multiple

Considérons la classe Doctorant qui hérite de Enseignant et Etudiant

from personne import Personne


from etudiant import Etudiant
from enseignant import Enseignant

class Doctorant(Enseignant, Etudiant):

c

def __init__(self, num: int = 0, nom: str = ’’, prenom: str = ’’,
I
ELH
salaire: int = 0, niveau: str = ’’, annee: str = ’’):
Enseignant.__init__(self, num, nom, prenom, salaire)
U
Etudiant.__init__(self, num, nom, prenom, niveau)
self.__annee = annee
L MO
f E
hre
@property
def annee(self) -> str:
c
c A
return self.__annee

@[Link]
def annee(self, annee) -> None:
self.__annee = annee

def __str__(self) -> str:


return Personne.__str__(self) + " " + str([Link]) + " "
+ [Link] + " " + self.__annee

H & H: Research and Training 67 / 117


Héritage Héritage multiple

Python

Dans [Link], créons un objet e type Doctorant


from doctorant import Doctorant
I c

H
EL ’austin’,
O U
doctorant = Doctorant (300, ’cooper’,
1700, ’doctorat’, ’1 èreM
fE L année’)

c h r e

# affichec A
print(doctorant)
300 austin cooper 1700 doctorat 1 ère anné
e

H & H: Research and Training 68 / 117


Polymorphisme Surcharge

Python

Surcharge (overload)

Définir dans une classe plusieurs méthodes avec


I c

le même nom
ELH
U
une signature différente
L MO
f E
hre
Si dans une classe, on a deux méthodes avec le même nom,
c
après. c A
Python remplace toujours la précédente par celle qui est définie

Donc pas de surcharge réelle en Python.

H & H: Research and Training 69 / 117


Polymorphisme Redéfinition

Python
Redéfinition (override)

Définir une méthode dans une classe qui est déjà définie dans la classe mère

Possible avec Python

I c
Deux manières de redéfinir une méthode
H
ELla classe fille différente
Proposer une nouvelle implémentation
et indépendante de celle de laM
U dans
O mère (simple comme si on
classe
L
f Eimplémentation qui fait référence à celle de
définit une nouvelle méthode)
Proposer uneh
c r e
nouvelle
la classeA
c mère

H & H: Research and Training 70 / 117


Polymorphisme Redéfinition

Python
Redéfinition (override)

Définir une méthode dans une classe qui est déjà définie dans la classe mère

Possible avec Python

I c
Deux manières de redéfinir une méthode
H
ELla classe fille différente
Proposer une nouvelle implémentation
et indépendante de celle de laM
U dans
O mère (simple comme si on
classe
L
f Eimplémentation qui fait référence à celle de
définit une nouvelle méthode)
Proposer uneh
c r e
nouvelle
la classeA
c mère

Exemple

Définir une méthode afficherDetails() dans Personne et la redéfinir dans Etudiant :


une fois sans faire référence à celle de la classe Personne et une autre en faisant référence.

H & H: Research and Training 70 / 117


Polymorphisme Redéfinition

Commençons par la définir afficherDetails() dans Personne

def afficher_details(self) -> None:


print(self.__prenom + " " + self.__nom)

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 71 / 117


Polymorphisme Redéfinition

Commençons par la définir afficherDetails() dans Personne

def afficher_details(self) -> None:


print(self.__prenom + " " + self.__nom)

Ensuite, on la redéfinit dans Etudiant

def afficher_details(self) -> None:


I c

ELH
print(self.__prenom + " " + self.__nom + " " + self.__niveau)

U
L MO
f E
chre
c A

H & H: Research and Training 71 / 117


Polymorphisme Redéfinition

Commençons par la définir afficherDetails() dans Personne

def afficher_details(self) -> None:


print(self.__prenom + " " + self.__nom)

Ensuite, on la redéfinit dans Etudiant

def afficher_details(self) -> None:


I c

ELH
print(self.__prenom + " " + self.__nom + " " + self.__niveau)

U
L MO
Testons tout cela dans le main)
f E
from personne import Personne
chre
c A
from etudiant import Etudiant

p = Personne(100, ’wick’, ’john’)
p.afficher_details()
# affiche john wick

etudiant = Etudiant(200, ’maggio’, ’toni’, "licence")


etudiant.afficher_details()
# affiche toni maggio licence

H & H: Research and Training 71 / 117


Polymorphisme Redéfinition

Python

On peut aussi utiliser l’implémentation de la classe Personne

def afficher_details(self) -> None:


Personne.afficher_details(self)
print(self.__niveau)
I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 72 / 117


Polymorphisme Redéfinition

Python

On peut aussi utiliser l’implémentation de la classe Personne

def afficher_details(self) -> None:


Personne.afficher_details(self)
print(self.__niveau)
I c

ELH
U
En testant, le résultat est le même
L MO
f E
etudiant = Etudiant(200, ’maggio’, ’toni’, "licence")
etudiant.afficher_details()
chre
c A
# affiche toni maggio
licence

H & H: Research and Training 72 / 117


Polymorphisme Redéfinition

Python

On peut aussi utiliser l’implémentation de la classe Personne

def afficher_details(self) -> None:


Personne.afficher_details(self)
print(self.__niveau)
I c

ELH
U
En testant, le résultat est le même
L MO
f E
etudiant = Etudiant(200, ’maggio’, ’toni’, "licence")
etudiant.afficher_details()
c hre
c A
# affiche toni maggio
licence
Refaire la même chose pour Enseignant

H & H: Research and Training 72 / 117


Classe et méthode abstraites

Python

Classe abstraite
hérite de la classe ABC (Abstract Base Class) du module abc

c

ne peut être instanciée si elle contient une ou plusieurs méthodes
I
abstraites
ELH
U
L MO
f E
c hre
c A

H & H: Research and Training 73 / 117


Classe et méthode abstraites

Python

Classe abstraite
hérite de la classe ABC (Abstract Base Class) du module abc

c

ne peut être instanciée si elle contient une ou plusieurs méthodes
I
abstraites
ELH
U
L MO
e f E
Si on déclare la classerPersonne
c
A ABCh abstraite
from abc cimport
class Personne(ABC):

# code précédent

H & H: Research and Training 73 / 117


Classe et méthode abstraites

Python
Méthode abstraite

C’est une méthode non implémentée (sans code)

Une méthode abstraite doit être déclarée dans une classe abstraite

I c

H
Une méthode abstraite doit être implémentée par les classes filles de la classe abstraite

EL
U
L MO
f E
c hre
c A

H & H: Research and Training 74 / 117


Classe et méthode abstraites

Python
Méthode abstraite

C’est une méthode non implémentée (sans code)

Une méthode abstraite doit être déclarée dans une classe abstraite

I c

H
Une méthode abstraite doit être implémentée par les classes filles de la classe abstraite

EL
U
L MO
f E
hre
Déclarons la méthode afficherDetails() comme abstraite dans Personne

c
c A
@abstractmethod


def afficher_details(self):
pass

H & H: Research and Training 74 / 117


Classe et méthode abstraites

Python
Méthode abstraite

C’est une méthode non implémentée (sans code)

Une méthode abstraite doit être déclarée dans une classe abstraite

I c

H
Une méthode abstraite doit être implémentée par les classes filles de la classe abstraite

EL
U
L MO
f E
hre
Déclarons la méthode afficherDetails() comme abstraite dans Personne

c
c A
@abstractmethod


def afficher_details(self):
pass

Sans oublier d’importer abstractmethod

from abc import ABC, abstractmethod

H & H: Research and Training 74 / 117


Classe et méthode abstraites

Python

En testant, le résultat est le même


I c
EL H
etudiant = Etudiant(200, ’maggio’, ’toni’, "licence"
U
)
L MO
fE
etudiant.afficher_details()
r e
# affiche toni maggio
c h
licence
c A

H & H: Research and Training 75 / 117


Indexeur

Python

I c

Définition
H
EL l’accès à un
Concept utilisé en programmation pourU
MO
faciliter
tableau d’objet défini dans unL objet.
funeE”classe” comme un tableau.
c h r e
(Autrement dit) Utiliser

c A

H & H: Research and Training 76 / 117


Indexeur

Python

Considérons la classe ListePersonnes suivante qui contient un


tableau de Personne
class ListePersonnes:
def __init__(self, personnes: list) -> None:
I c

self.__personnes = personnes
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 77 / 117


Indexeur

Python

Considérons la classe ListePersonnes suivante qui contient un


tableau de Personne
class ListePersonnes:
def __init__(self, personnes: list) -> None:
I c

self.__personnes = personnes
ELH
U
L MO
f E
A c hre
Comment faire pour enregistrer des personnes dans le tableau
personnes et les récupérer facilement en faisant listePersonnes[i]
c

p = Personne(100, ’wick’, ’john’)
p2 = Personne(101, ’dalton’, ’jack’)
mes_amis = ListePersonnes([p, p2])
print(mes_amis[0])

H & H: Research and Training 77 / 117


Indexeur getitem ()

Python

Pour pouvoir accéder à un élément d’indice i, on ajoute la


méthode getitem ()
I c

class ListePersonnes: E LH
U
O list) -> None:
M
def __init__(self, personnes:
L
h r e fE
self.__personnes = personnes

A c
def __getitem__(self, i):
c
return self.__personnes[i]

H & H: Research and Training 78 / 117


Indexeur getitem ()

Python

Dans [Link]
from listepersonnes import ListePersonnes
I c

from personne import Personne
EL H
O U
M
p = Personne(100, ’wick’, ’john’)
L
r e f E
p2 = Personne(101, ’dalton’, ’jack’)
c h
mes_amis = ListePersonnes([p, p2])

c A
print(mes_amis[0])
# affiche 100 john wick

H & H: Research and Training 79 / 117


Indexeur setitem ()

Python

Pour pouvoir modifier un élément en utilisant son indice, on


ajoute la méthode setitem ()
class ListePersonnes:
I c

def __init__(self, personnes: list) -> None:
ELH
U
self.__personnes = personnes
L MO
f E
hre
def __getitem__(self, i):
c
c A
return self.__personnes[i]

def __setitem__(self, key, value):
self.__personnes[key] = value

H & H: Research and Training 80 / 117


Indexeur setitem ()

Python

Dans [Link]
from listepersonnes import ListePersonnes
from personne import Personne
I c

EL H
O
p = Personne(100, ’wick’, ’john’)U
L M’jack’)
fE
p2 = Personne(101, ’dalton’,

mes_amis[1] A c h r e
mes_amis = ListePersonnes([p,
= Personne(102,
p2])
’hadad’, ’karim’)
c
print(mes_amis[1])
# affiche 102 karim hadad

H & H: Research and Training 81 / 117


Indexeur len ()

Python

Pour pouvoir utiliser la fonction len(), on ajoute la méthode


len ()
class ListePersonnes:
I
def __init__(self, personnes: list) -> None:c

self.__personnes = personnes
EL H
U
L MO
def __getitem__(self, i):
r e fE
return self.__personnes[i]
h
c
def c A
__setitem__(self, key, value):
self.__personnes[key] = value

def __len__(self):
return len(self.__personnes)

H & H: Research and Training 82 / 117


Indexeur len ()

Python

Dans [Link]
from listepersonnes import ListePersonnes
I c

from personne import Personne
EL H
O U
M
p = Personne(100, ’wick’, ’john’)
L
r e f E
p2 = Personne(101, ’dalton’, ’jack’)
c h
mes_amis = ListePersonnes([p, p2])

c A
print(len(mes_amis))
# affiche 2

H & H: Research and Training 83 / 117


Indexeur len ()

Python

Exercice
I c
Dans Personne, définir un indexeur sur les
H
ELadresses
U
L
Dans le Main, vérifier qu’il est MO d’accéder à l’adresse
possible
r e fE
d’une personne de ListePersonnes
h
en faisant par exemple
c
c A
mes amis[0][0]

H & H: Research and Training 84 / 117


Itérateur

Python

Itérateur ?


Concept utilisé dans plusieurs langages de programmation
I c
comme C++ et Java
EL H
U
OPython itérables comme les
M
Objet utilisé pour itérer sur des objets
L
f E les ensembles et les chaı̂nes
listes, les tuples, les dictionnaires,
de caractères hre
A c
c
Initialis
é avec la méthode iter ()
Utilisant la méthode next () pour récupérer l’élément suivant

H & H: Research and Training 85 / 117


Itérateur

Python

Considérons la liste suivante


liste = [2, 3, 8, 5]
I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 86 / 117


Itérateur

Python

Considérons la liste suivante


liste = [2, 3, 8, 5]
I c

ELH
U
L MO
f E
hre
Pour parcourir la liste, plusieurs solutions possibles
c
c A
utiliser une boucle while ou for

utiliser un itérateur

H & H: Research and Training 86 / 117


Itérateur

Python

Déclarons l’itérateur
iterateur = iter(liste)

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 87 / 117


Itérateur

Python

Déclarons l’itérateur
iterateur = iter(liste)

I c

Pour demander la première valeur ELH
OU
print(iterateur.__next__())M
fE L
# affiche 2
c h r e
c A

H & H: Research and Training 87 / 117


Itérateur

Python

Déclarons l’itérateur
iterateur = iter(liste)

I c

Pour demander la première valeur ELH
OU
print(iterateur.__next__())M
fE L
# affiche 2
c h r e
c A
Ou en plus simple
print(next(iterateur))
# affiche 5

H & H: Research and Training 87 / 117


Itérateur

Python
Utilisons une boucle while pour itérer sur tous les éléments de la liste
while True:
print(next(iterateur))
# affiche
# 2
I c

# 3
ELH
# 8
U
# 5
L MO
# Traceback (most recent call last):
f E
#
hre
File "C:/Users/elmou/PycharmProjects/cours-poo/main.
c
c A
py", line 6, in <module>
#
print(next(iterateur))
# StopIteration

H & H: Research and Training 88 / 117


Itérateur

Python
Utilisons une boucle while pour itérer sur tous les éléments de la liste
while True:
print(next(iterateur))
# affiche
# 2
I c

# 3
ELH
# 8
U
# 5
L MO
# Traceback (most recent call last):
f E
#
hre
File "C:/Users/elmou/PycharmProjects/cours-poo/main.
c
c A
py", line 6, in <module>
#
print(next(iterateur))
# StopIteration

Une exception sera levée lorsqu’il n’y a plus de valeurs à retourner

H & H: Research and Training 88 / 117


Itérateur

Python

Pour résoudre le problème précédent


while True:
try:
I c

print(next(iterateur))
ELH
U
except StopIteration:
L MO
break
f E
# affiche
chre
c A
# 2
# 3
# 8
# 5

H & H: Research and Training 89 / 117


Itérateur

Python

Pour qu’une classe soit itérable, il faut implémenter les deux


méthodes iter () et next ()
class Nombre:
def __iter__(self):
I c

[Link] = 1
ELH
U
MO
return self

f E L
hre
def __next__(self):
c
c A
if [Link] <= 20:

x = [Link]
[Link] += 1
return x
else:
raise StopIteration

H & H: Research and Training 90 / 117


Itérateur

Python

La classe Nombre retourne 20 valeurs incrémentales commençant


par 1
I c

nombre = Nombre()
ELH
U
MO
iter = iter(nombre)

f E L
hre
for val in iter:
c
c A
print(val, end=" ")

# affiche 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
18 19 20

H & H: Research and Training 91 / 117


Itérateur

Python

I c

Pour la suite EL H
U
()O
Commentez la méthode getitem M
E L dans ListePersonnes.

c h ref
c A

H & H: Research and Training 92 / 117


Itérateur

Python
Et si on veut parcourir les objets Personne de la classe
ListePersonnes comme si c’était une vraie liste, c’est-à-dire :
from listepersonnes import ListePersonnes
from personne import Personne
I c

ELH
U
p = Personne(100, ’wick’, ’john’)
O
L M’jack’)
p2 = Personne(101, ’dalton’,

h r e fE
mes_amis = ListePersonnes([p, p2])

A c
c
for personne in mes_amis:
print(personne)

Un message d’erreur nous informe que ListePersonnes n’est pas


itérable
H & H: Research and Training 93 / 117
Itérateur

Python

I c

Exercice
E LH
U
O () dans
M
Ajoutez les méthodes iter () et next
L
ListePersonnes pour qu’elle
r e f Esoit itérable.
A ch
c

H & H: Research and Training 94 / 117


Itérateur

Python
Solution
class ListePersonnes:
def __init__(self, personnes: list) -> None:
self.__personnes = personnes
I c

self.__indice = 0
ELH
U
def __iter__(self):
return self
L MO
re f E
c h
def __next__(self):
A
ifcself.__indice
raise >= len(self.__personnes):
StopIteration
else:
value = self.__personnes[self.__indice]
self.__indice += 1
return value

H & H: Research and Training 95 / 117


Opérateur

Python

Définition
I c
H
ELC++ (surcharge
U
Concept introduit initialement par le langage
d’opérateurs)
L MO
r e
Permettant de surcharger
h f Eles opérateurs de comparaison ou les
A c étiques déjà utilisés pour les types prédéfinis
opérateurs arithm
c

H & H: Research and Training 96 / 117


Opérateur

Python

Opérateurs de comparaison et méthodes à implémenter


== : eq ()
I c

!= : ne () ELH
U
>= : ge () L MO
f E
<= : le ()
chre
>:
gtc()A
< : lt ()

H & H: Research and Training 97 / 117


Opérateur

Python

Opérateurs arithmétiques et méthodes à implémenter


+ : add ()
I c

* : mul ()
ELH
U
** : pow ()
L MO
f E
hre
/ : truediv ()
c
c A

// : floordiv ()
% : mod ()
...

H & H: Research and Training 98 / 117


Opérateur

Python
Exemple

from personne import Personne

p = Personne(100, ’wick’, ’john’)


p2 = Personne(100, ’wick’, ’john’)
if p == p2:
I c

print(True)
ELH
else:
U
MO
print(False)
# affiche False

f E L
chre
c A

H & H: Research and Training 99 / 117


Opérateur

Python
Exemple

from personne import Personne

p = Personne(100, ’wick’, ’john’)


p2 = Personne(100, ’wick’, ’john’)
if p == p2:
I c

print(True)
ELH
else:
U
MO
print(False)
# affiche False

f E L
chre
Remarques c A

Les deux objets précédents ne sont pas égaux car ils occupent deux espaces mémoires
différents

Pour définir une nouvelle règle de comparaison d’objets, on doit implémenter la méthode
eq () dans la classe Personne

H & H: Research and Training 99 / 117


Opérateur eq ()

Python
Ajoutons l’implémentation de la méthode eq () dans la classe Personne

def __eq__(self, p: "Personne") -> bool:


return p.__nom == self.__nom and p.__prenom == self.
__prenom and p.__num == self.__num

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 100 / 117


Opérateur eq ()

Python
Ajoutons l’implémentation de la méthode eq () dans la classe Personne

def __eq__(self, p: "Personne") -> bool:


return p.__nom == self.__nom and p.__prenom == self.
__prenom and p.__num == self.__num

I c

E LH
En testant le main précédent, le résultat est OU
L M
from personne import Personne
r ef E
c h
c A ’wick’,
p = Personne(100,
p2 = Personne(100,
’john’)
’wick’, ’john’)
if p == p2:
print(True)
else:
print(False)
# affiche True

H & H: Research and Training 100 / 117


Opérateur gt ()

Python

I c

H
Ajoutons l’implémentation de la méthode gt () dans la classe
EL
Personne
U
L MO
def __gt__(self, other: "Personne"):
return self._num f>E
c h r e other._num

c A

H & H: Research and Training 101 / 117


Opérateur gt ()

Python
testons cela dans le main

from personne import Personne

p = Personne(100, ’wick’, ’john’)


p2 = Personne(101, ’wick’, ’john’)
I c

ELH
U
MO
if p2 > p:
print(True)
else:
f E L
print(False)
chre
c A
# affiche True

if p > p2:

print(True)
else:
print(False)
# affiche False

H & H: Research and Training 102 / 117


Opérateur add ()

Python
Ajoutons l’implémentation de la méthode add () dans la classe Enseignant

def __add__(self, i: int):


self.__salaire += i
return self

I c

ELH
U
L MO
f E
chre
c A

H & H: Research and Training 103 / 117


Opérateur add ()

Python
Ajoutons l’implémentation de la méthode add () dans la classe Enseignant

def __add__(self, i: int):


self.__salaire += i
return self

I c

ELH
U
testons cela dans [Link]
L MO
f E
hre
from enseignant import Enseignant

c
c A
enseignant = Enseignant(300, ’dalton’, ’jack’, 1700)

print(enseignant)
# affiche 300 jack dalton 1700

print(enseignant + 200)
# affiche 300 jack dalton 1900

H & H: Research and Training 103 / 117


Généricité

Python

I c
Généricité
L H
ETypeScript,
O
Concept connu dans plusieurs LOO (Java, U C#)
M
L classes s’adaptant avec plusieurs
f E
Objectif : définir des fonctions,
re
types de données
c h
c A

H & H: Research and Training 104 / 117


Généricité

Python

Exemple

I c
si on a besoin d’une classe dont les méthodes effectuent les

mêmes opérations quel que soit le type d’attributs
EL H
somme pour entiers ou réels,
O U
L
concaténation pour chaı̂nes M
de caractères,
e
ou logique pourrbool
E
f éens...
A c h
...
c
Impossible sans définir plusieurs classes (une pour chaque
type)

H & H: Research and Training 105 / 117


Généricité

Python
Solution avec la généricité

from typing import TypeVar, Generic

T = TypeVar(’T’)

I c

class Operation (Generic[T]):

ELH
def __init__(self, var1: T, var2: T):
U
self.__var1 = var1
L MO
self.__var2 = var2
f E
def plus(self):
c hre
c A
if type(self.__var1) is str :

return self.__var1 + self.__var2
elif type(self.__var1) is int and type(self.__var2) is int:
return self.__var1 + self.__var2;
elif type(self.__var1) is bool and type(self.__var2) is bool:
return self.__var1 | self.__var2
else:
raise TypeError("error")

H & H: Research and Training 106 / 117


Généricité

Python
Nous pouvons donc utiliser la même méthode pour plusieurs types différents
from operation import Operation

try:
operation1 = Operation[int](5, 3)
print([Link]())
I c

# affiche 8

ELH
U
MO
operation2 = Operation[str]("bon", "jour")
print([Link]())
# affiche bonjour
f E L
chre
operation3 = Operation[bool](True, False)

c A
print([Link]())

# affiche true

operation4 = Operation[bool](2.8, 4.9)


print([Link]())
# affiche problème de type

except TypeError:
print ("problème de type")

H & H: Research and Training 107 / 117


Énumération

Python

Énumération
est un ensemble de noms liés à des valeurs constantes et
uniques (nom + valeur = membre)
I c

est itérable ELH
U
L MO
f E
chre
c A

H & H: Research and Training 108 / 117


Énumération

Python

Énumération
est un ensemble de noms liés à des valeurs constantes et
uniques (nom + valeur = membre)
I c

est itérable ELH
U
L MO
f E
A c hre
Exemple : définissons l’énumération Animal
c
from enum import Enum

Animal = Enum(’Animal’, ’CHAT CHIEN CHAMEAU CHEVAL


SOURIS’)

H & H: Research and Training 108 / 117


Énumération

Python

Pour accéder à la valeur ou le nom d’un membre d’une énumération

print ([Link])
# affiche 2

I c

print ([Link])
# affiche chien
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 109 / 117


Énumération

Python

Pour accéder à la valeur ou le nom d’un membre d’une énumération

print ([Link])
# affiche 2

I c

print ([Link])
# affiche chien
ELH
U
L MO
f E
e deux écritures suivantes sont équivalentes
Pour récupérer un membre,rles
c h
c A
print ([Link])
# affiche [Link]

print (Animal[’CHIEN’])
# affiche [Link]

H & H: Research and Training 109 / 117


Énumération

Python

Pour récupérer le nom associée à une valeur


print (Animal(1))
I c

# affiche [Link]
ELH
U
L MO
f E
chre
c A

H & H: Research and Training 110 / 117


Énumération

Python

Pour récupérer le nom associée à une valeur


print (Animal(1))
I c

# affiche [Link]
ELH
U
L MO
f E
reération
h
Pour itérer sur une énum
c
for animal c inAAnimal:
print(animal)

H & H: Research and Training 110 / 117


Énumération

Python

Pour modifier les valeurs par défaut associées aux noms, on déclare
l’énumération comme une classe qui hérite de Enum

from enum import Enum

I c

class Animal(Enum):
CHAT = 1
ELH
U
MO
CHIEN = 3
CHAMEAU = 2
CHEVAL = 4
f E L
SOURIS = 6
chre
c A

H & H: Research and Training 111 / 117


Énumération

Python

Pour modifier les valeurs par défaut associées aux noms, on déclare
l’énumération comme une classe qui hérite de Enum

from enum import Enum

I c

class Animal(Enum):
CHAT = 1
ELH
U
MO
CHIEN = 3
CHAMEAU = 2
CHEVAL = 4
f E L
SOURIS = 6
chre
c A

Pour récupérer la valeur associée à un nom (rien ne change)

print([Link])
# affiche 2

H & H: Research and Training 111 / 117


Énumération

Python

Deux noms différents peuvent avoir la même valeur

from enum import Enum

class Animal(Enum):
I c

CHAT = 1
CHIEN = 3
ELH
U
MO
CHAMEAU = 2
CHEVAL = 2
SOURIS = 6
f E L
chre
c A

H & H: Research and Training 112 / 117


Énumération

Python

Deux noms différents peuvent avoir la même valeur

from enum import Enum

class Animal(Enum):
I c

CHAT = 1
CHIEN = 3
ELH
U
MO
CHAMEAU = 2
CHEVAL = 2
SOURIS = 6
f E L
A c hre
c
En accédant via une valeur, on récupère le premier membre ayant la valeur
recherchée

print(Animal(2))
# affiche [Link]

H & H: Research and Training 112 / 117


Énumération

Python

Pour forcer l’unicité des valeurs, on utilise le décorateur @unique


(ValueError : duplicate values found in <enum ’Animal’> :
CHEVAL -> CHAMEAU)
I c

from enum import Enum, unique
ELH
U
@unique
L MO
f E
hre
class Animal(Enum):
CHAT = 1 c
CHIEN = 3 c A

CHAMEAU = 2
CHEVAL = 2
SOURIS = 6

H & H: Research and Training 113 / 117


Énumération

Python

Pour affecter des valeurs auto-increment aux différents noms


from enum import Enum, auto

I c

class Animal(Enum):
CHAT = auto() ELH
U
CHIEN = auto()
L MO
CHAMEAU = auto()
f E
CHEVAL = auto()
chre
c A
SOURIS = auto()

for animal in Animal:
print([Link])
# affiche 1 2 3 4 5

H & H: Research and Training 114 / 117


Introspection

Python

Fonction dir()
I c
sans paramètre : retourne la liste de méthodesE H
L et attributs
U
disponibles dans le module
L MO
avec paramètre (objet ou
h
attributs définisc(et
efés)E
rhérit classe) : retourne la liste de méthodes et
de la classe
c A

H & H: Research and Training 115 / 117


Introspection

Python

Quelques constantes sur les fonctions

print(dir())
# affiche [’__annotations__’, ’__builtins__’, ’__cached__’, ’
c
__doc__’, ’__file__’, ’__loader__’, ’__name__’, ’__package__
I
’, ’__spec__’]
E L H
U
print(dir(personne))
L MO ’__dict__’, ’__dir__’, ’
f E ’__hash__’,
# affiche [’__class__’, ’__delattr__’,

h r e
__doc__’, ’__eq__’, ’__format__’, ’__ge__’, ’
c ’__le__’, ’__lt__’, ’__module__’,
__getattribute__’, ’__gt__’, ’__init__’, ’

A
c’__new__’, ’__reduce__’, ’__reduce_ex__’, ’__repr__
__init_subclass__’,
__ne__’,

’, ’__setattr__’, ’__sizeof__’, ’__str__’, ’__subclasshook__


’, ’__weakref__’, ’increment’, ’nbr_personnes’, ’nom’, ’num
’, ’prenom’]

H & H: Research and Training 116 / 117


Conventions

Python

Conventions
Une classe par fichier
I c
H
EL d’une classe
U
Deux lignes vides avant et après la déclaration
O
LlaM
f E pour chaque méthode publique à
Une ligne vide avant et après déclaration d’une méthode
Un message de h r e
cla ligne contenant le mot-clé def
documentation
c
à placer aprA
ès
Une classe de test par classe

H & H: Research and Training 117 / 117

Vous aimerez peut-être aussi