23/01/2023 13:53 Classes et objets — Cours Python
Classes et objets
Contenu
Brève introduction à la Programmation Orientée Objet
Les notions de classe et d’objet
La notion d’encapsulation
Attributs et méthodes de classe
Cette page s’appuie sur le livre de Gérard Swinnen « Apprendre à programmer avec Python 3 »
disponible sous licence CC BY-NC-SA 2.0. L’introduction à la programmation orientée objet est
inspirée par le livre de Claude Delannoy « Programmer en Java » (Eyrolles) que vous êtes invités
à consulter si vous souhaitez découvrir le langage Java.
Python est un langage qui permet la Programmation Orientée Objet (POO).
Brève introduction à la Programmation Orientée
Objet
Nous avons vu plusieurs types de base en Python (int pour les entiers, float pour les flottants,
str pour les chaînes de caractères, etc.). La notion de classe va en quelque sorte nous permettre
de généraliser la notion de « type » afin de créer de nouvelles structures de données.
Une classe définit des attributs et des méthodes. Par exemple, imaginons une classe Voiture
qui servira à créer des objets qui sont des voitures. Cette classe va pouvoir définir un attribut
couleur, un attribut vitesse, etc. Ces attributs correspondent à des propriétés qui peuvent
exister pour une voiture. La classe Voiture pourra également définir une méthode rouler(). Une
méthode correspond en quelque sorte à une action, ici l’action de rouler peut être réalisée pour
une voiture.
Si on imagine une classe Avion, elle pourra définir une méthode voler(). Elle pourra aussi définir
une méthode rouler(). Par contre, la classe Voiture n’aura pas de méthode voler() car une
voiture ne peut pas voler. De même, la classe Avion pourra avoir un attribut altitude mais ce ne
sera pas le cas pour la classe Voiture.
Après avoir présenté la notion de classe, nous allons voir la notion d”objet. On dit qu’un objet
est une instance de classe. Si on revient à la classe Voiture, nous pourrons avoir plusieurs
voitures qui seront chacune des instances bien distinctes. Par exemple, la voiture de Jonathan,
qui est de couleur rouge avec une vitesse de 30 km/h, est une instance de la classe Voiture,
c’est un objet. De même, la voiture de Denis, qui est de couleur grise avec une vitesse de 50
km/h, est un autre objet. Nous pouvons donc avoir plusieurs objects pour une même classe, en
particulier ici deux objets (autrement dit : deux instances de la même classe). Chacun des objets
a des valeurs qui lui sont propres pour les attributs.
[Link] 1/10
23/01/2023 13:53 Classes et objets — Cours Python
Les notions de classe et d’objet
Définition d’une classe Point
Voici comment définir une classe appelée ici Point.
class Point:
"Definition d'un point geometrique"
Par convention en Python, le nom identifiant une classe (qu’on appelle aussi son identifiant)
débute par une majuscule. Ici Point débute par un P majuscule.
Création d’un objet de type Point
Point()
Ceci crée un objet de type Point. En POO, on dit que l’on crée une instance de la classe Point.
Une phrase emblématique de la POO consiste à dire qu”un objet est une instance de classe.
Il faut bien noter que pour créer une instance, on utilise le nom de la classe suivi de parenthèses.
Nous verrons par la suite qu’il peut y avoir des arguments entre ces parenthèses.
Affectation à une variable de la référence à un objet
Nous venons de définir une classe Point. Nous pouvons dès à présent nous en servir pour créer
des objets de ce type, par instanciation. Créons par exemple un nouvel objet et mettons la
référence à cet objet dans la variable p :
>>> p = Point()
Avertissement
Comme pour les fonctions, lors de l’appel à une classe dans une instruction pour créer
un objet, il faut toujours indiquer des parenthèses (même si aucun argument n’est
transmis). Nous verrons un peu plus loin que ces appels peuvent se faire avec des
arguments (voir la notion de constructeur).
Remarquez bien cependant que la définition d’une classe ne nécessite pas de
parenthèses (contrairement à ce qui de règle lors de la définition des fonctions), sauf si
nous souhaitons que la classe en cours de définition dérive d’une autre classe
préexistante (ceci sera expliqué plus loin).
Nous pouvons dès à présent effectuer quelques manipulations élémentaires avec notre nouvel
objet dont la référence est dans p.
Exemple
>>> print(p)
<__main__.Point instance at 0x012CAF30>
Le message renvoyé par Python indique que p contient une référence à une instance de la classe
Point, qui est définie elle-même au niveau principal du programme. Elle est située dans un
emplacement bien déterminé de la mémoire vive, dont l’adresse apparaît ici en notation
hexadécimale.
>>> print(p.__doc__)
Definition d'un point geometrique
[Link] 2/10
23/01/2023 13:53 Classes et objets — Cours Python
On peut noter que les chaînes de documentation de divers objets Python sont associées à
l’attribut prédéfini __doc__:.
Exemple avec deux objets
a = Point()
b = Point()
La variable a va contenir une référence à un objet.
>>> print(a)
<__main__.Point instance at 0x012CADC8>
De même b va contenir une référence à un autre objet.
>>> print(b)
<__main__.Point instance at 0x012CAF08>
Nous avons ici 2 instances de la classe Point (2 objets) :
la première à laquelle on fait référence au moyen de la variable a,
la seconde à laquelle on fait référence au moyen de la variable b.
On fait bien ici la distinction entre classe et objet. Ici nous avons une seule classe Point, et deux
objets de type Point.
Définition des attributs
class Point:
"Definition d'un point geometrique"
p = Point()
p.x = 1
p.y = 2
print("p : x =", p.x, "y =", p.y)
Exécuter
L’objet dont la référence est dans p possède deux attributs : x et y.
La syntaxe pour accéder à un attribut est la suivante : on va utiliser la variable qui contient la
référence à l’objet et on va mettre un point . puis le nom de l’attribut.
Exemple
class Point:
"Definition d'un point geometrique"
a = Point()
a.x = 1
a.y = 2
b = Point()
b.x = 3
b.y = 4
print("a : x =", a.x, "y =", a.y)
print("b : x =", b.x, "y =", b.y)
Exécuter
On a 2 instances de la classe Point, c’est-à-dire 2 objets de type Point. Pour chacun d’eux, les
attributs prennent des valeurs qui sont propres à l’instance.
[Link] 3/10
23/01/2023 13:53 Classes et objets — Cours Python
Distinction entre variable et objet
L’exemple suivant montre bien la distinction entre variable et objet :
class Point:
"Definition d'un point geometrique"
a = Point()
a.x = 1
a.y = 2
b = a
print("a : x =", a.x, "y =", a.y)
print("b : x =", b.x, "y =", b.y)
a.x = 3
a.y = 4
print("a : x =", a.x, "y =", a.y)
print("b : x =", b.x, "y =", b.y)
Exécuter
Ici les variables a et b font référence au même objet. En effet, lors de l’affectation b = a, on met
dans la variable b la référence contenue dans la variable a. Par conséquent, toute modification
des valeurs des attributs de l’objet dont la référence est contenue dans a entraîne une
modification pour b.
Avertissement
Par abus de langage on parlera parfois de l’objet a alors qu’il s’agira en fait de l’objet
auquel a fait référence.
Définition des méthodes
class Point:
def deplace(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy
Cette classe possède une méthode : deplace().
Pour définir une méthode, il faut :
1. indiquer son nom (ici deplace()).
2. indiquer les arguments entre des parenthèses. Le premier argument d’une méthode doit
être self.
Pour accéder aux méthodes d’un objet, on indique :
1. le nom de la variable qui fait référence à cet objet
2. un point
3. le nom de la méthode
[Link](3, 5)
[Link] 4/10
23/01/2023 13:53 Classes et objets — Cours Python
Avertissement
Lors de l’appel de la méthode, le paramètre self n’est pas utilisé et la valeur qu’il
prend est la référence à l’objet. Il y a donc toujours un paramètre de moins que lors de
la définition de la méthode.
Exemple
class Point:
def deplace(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy
a = Point()
a.x = 1
a.y = 2
print("a : x =", a.x, "y =", a.y)
[Link](3, 5)
print("a : x =", a.x, "y =", a.y)
Exécuter
La notion de constructeur
Si lors de la création d’un objet nous voulons qu’un certain nombre d’actions soit réalisées (par
exemple une initialisation), nous pouvons utiliser un constructeur.
Un constructeur n’est rien d’autre qu’une méthode, sans valeur de retour, qui porte un nom
imposé par le langage Python : __init__(). Ce nom est constitué de init entouré avant et après
par __ (deux fois le symbole underscore _, qui est le tiret sur la touche 8). Cette méthode sera
appelée lors de la création de l’objet. Le constructeur peut disposer d’un nombre quelconque de
paramètres, éventuellement aucun.
Exemple sans paramètre
class Point:
def __init__(self):
self.x = 0
self.y = 0
a = Point()
print("a : x =", a.x, "y =", a.y)
a.x = 1
a.y = 2
print("a : x =", a.x, "y =", a.y)
Exécuter
Dans cet exemple, nous avons pu définir des valeurs par défaut pour les attributs grâce au
constructeur.
Exemple avec paramètres
class Point:
def __init__(self, abs, ord):
self.x = abs
self.y = ord
a = Point(1, 2)
print("a : x =", a.x, "y =", a.y)
Exécuter
Autre exemple avec paramètres
[Link] 5/10
23/01/2023 13:53 Classes et objets — Cours Python
Dans l’exemple suivant, on utilise les mêmes noms pour les paramètres du constructeur et les
attributs. Ceci ne pose pas de problème car ces variables ne sont pas dans le même espace de
noms. Les paramètres du constructeur sont des variables locales, comme c’est habituellement le
cas pour une fonction. Les attributs de l’objet sont eux dans l’espace de noms de l’instance. Les
attributs se distinguent facilement car ils ont self devant.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
a = Point(1, 2)
print("a : x =", a.x, "y =", a.y)
Exécuter
Exemple complet
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def deplace(self, dx, dy):
self.x = self.x + dx
self.y = self.y + dy
a = Point(1, 2)
b = Point(3, 4)
print("a : x =", a.x, "y =", a.y)
print("b : x =", b.x, "y =", b.y)
[Link](3, 5)
[Link](-1, -2)
print("a : x =", a.x, "y =", a.y)
print("b : x =", b.x, "y =", b.y)
Exécuter
Exercice
Modifier le programme de façon à ajouter deux autres objets de type Point. Ils seront référencés
par des variables c et d.
Exercice
Définir une classe Point3D qui sera analogue à la classe Point mais pour des points dans l’espace
à 3 dimensions. Créer deux objets de type Point3D qui seront référencés par les variables a3D et
b3D. Initialiser ces points et afficher leurs coordonnées x, y, z.
La notion d’encapsulation
Le concept d”encapsulation est un concept très utile de la POO. Il permet en particulier d’éviter
une modification par erreur des données d’un objet. En effet, il n’est alors pas possible d’agir
directement sur les données d’un objet ; il est nécessaire de passer par ses méthodes qui jouent
le rôle d’interface obligatoire.
Définition d’attributs privés
On réalise la protection des attributs de notre classe Point grâce à l’utilisation d’attributs
privées. Pour avoir des attributs privés, leur nom doit débuter par __ (deux fois le symbole
underscore _, qui est le tiret sur la touche 8).
class Point:
def __init__(self, x, y):
self.__x = x
self.__y = y
[Link] 6/10
23/01/2023 13:53 Classes et objets — Cours Python
Il n’est alors plus possible de faire appel aux attributs __x et __y depuis l’extérieur de la classe
Point.
>>> p = Point(1, 2)
>>> p.__x
Traceback (most recent call last):
File "<pyshell#9>", line 1, in
p.__x
AttributeError: Point instance has no attribute '__x'
Il faut donc disposer de méthodes qui vont permettre par exemple de modifier ou d’afficher les
informations associées à ces variables.
class Point:
def __init__(self, x, y):
self.__x = x
self.__y = y
def deplace(self, dx, dy):
self.__x = self.__x + dx
self.__y = self.__y + dy
def affiche(self):
print("abscisse =", self.__x, "ordonnee =", self.__y)
a = Point(2, 4)
[Link]()
[Link](1, 3)
[Link]()
Exécuter
Accesseurs et mutateurs
Parmi les différentes méthodes que comporte une classe, on a souvent tendance à distinguer :
les constructeurs ;
les accesseurs (en anglais accessor) qui fournissent des informations relatives à l’état d’un
objet, c’est-à-dire aux valeurs de certains de ses attributs (généralement privés) sans les
modifier ;
les mutateurs (en anglais mutator) qui modifient l’état d’un objet, donc les valeurs de
certains de ses attributs.
On rencontre souvent l’utilisation de noms de la forme get_XXXX() pour les accesseurs et
set_XXXX() pour les mutateurs, y compris dans des programmes dans lesquels les noms de
variable sont francisés. Par exemple, pour la classe Point sur laquelle nous avons déjà travaillé
on peut définir les méthodes suivantes :
Exemple :
[Link] 7/10
23/01/2023 13:53 Classes et objets — Cours Python
class Point:
def __init__(self, x, y):
self.set_x(x)
self.set_y(y)
def get_x(self):
return self.__x
def set_x(self, x):
self.__x = x
def get_y(self):
return self.__y
def set_y(self, y):
self.__y = y
a = Point(3, 7)
print("a : abscisse =", a.get_x())
print("a : ordonnee =", a.get_y())
a.set_x(6)
a.set_y(10)
print("a : abscisse =", a.get_x())
print("a : ordonnee =", a.get_y())
Exécuter
L’utilisation d’un mutateur pour fixer la valeur d’un attribut autorise la possibilité d’effectuer un
contrôle sur les valeurs de l’attribut. Par exemple, il serait possible de n’autoriser que des valeurs
positives pour les attributs privés __x et __y.
Notez qu’il n’est pas toujours prudent de prévoir une méthode d’accès pour chacun des
attributs privés d’un objet. En effet, il ne faut pas oublier qu’il doit toujours être possible de
modifier l’implémentation d’une classe de manière transparente pour son utilisateur.
Exemple avec le décorateur @property
Il existe en Python une autre approche pour gérer ce type de situation. Elle utilise le décorateur
@property.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@property
def x(self):
return self._x
@[Link]
def x(self, x):
self._x = x
@property
def y(self):
return self._y
@[Link]
def y(self, y):
self._y = y
a = Point(3, 7)
print("a : abscisse =", a.x)
print("a : ordonnee =", a.y)
a.x = 6
a.y = 10
print("a : abscisse =", a.x)
print("a : ordonnee =", a.y)
Exécuter
On utilise des attributs précédés par un underscore. Il s’agit d’une convention pour indiquer que
ces attributs ne doivent pas être utilisés en dehors de la classe et qu’il faut utiliser les accesseurs
et mutateurs pour les manipuler.
[Link] 8/10
23/01/2023 13:53 Classes et objets — Cours Python
Exercice
Définir une classe Point3D analogue à la classe Point mais pour des points dans l’espace à 3
dimensions.
Attributs et méthodes de classe
Attributs de classe
Exemple :
class A:
nb = 0
def __init__(self, x):
print("creation objet de type A")
self.x = x
[Link] = [Link] + 1
print("A : nb = ", [Link])
print("Partie 1")
a = A(3)
print("A : nb = ", [Link])
print("a : x = ", a.x, " nb = ", [Link])
print("Partie 2")
b = A(6)
print("A : nb = ", [Link])
print("a : x = ", a.x, " nb = ", [Link])
print("b : x = ", b.x, " nb = ", [Link])
c = A(8)
print("Partie 3")
print("A : nb = ", [Link])
print("a : x = ", a.x, " nb = ", [Link])
print("b : x = ", b.x, " nb = ", [Link])
print("c : x = ", c.x, " nb = ", [Link])
Exécuter
Méthodes de classe
Exemple :
class A:
nb = 0
def __init__(self):
print("creation objet de type A")
[Link] = [Link] + 1
print("il y en a maintenant ", [Link])
@classmethod
def get_nb(cls):
return [Link]
print("Partie 1 : nb objets = ", A.get_nb())
a = A()
print("Partie 2 : nb objets = ", A.get_nb())
b = A()
print("Partie 3 : nb objets = ", A.get_nb())
Exécuter
Pour créer une méthode de classe, il faut la faire précéder d’un « décorateur » : @classmethod
Le premier argument de la méthode de classe doit être cls.
Voir aussi
[Link]
[Link] 9/10
23/01/2023 13:53 Classes et objets — Cours Python
By David Cassagne
Last updated on 22 oct. 2022.
Licence CC BY-NC-SA 4.0.
[Link] 10/10