Les classes en Python
Les classes sont des structures de données qui permettent de regrouper des données et des fonctions qui agissent sur ces données. Un objet est une instance d'une classe. Le concept de programmation orientée objet remonte aux années 1960 , mais il a été popularisé par des langages comme C++, Java et Python.
Distinction entre classe et objet
Une classe est un modèle pour créer des objets. Elle définit les attributs et les méthodes que les objets de la classe auront. Un objet est une instance d'une classe et il est créé à l'aide du constructeur de la classe. Autrement dit, la classe est le plan pour construire des objets. Avec un même plan, vous pouvez construire plusieurs objets.
Définir une classe
En Python, une classe est définie à l'aide du mot-clé class
. Voici un exemple
de classe qui définit un point dans un espace à deux dimensions :
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, other):
return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
Dans cet exemple, la classe Point
a deux attributs x
et y
qui représentent
les coordonnées du point. La méthode __init__
est un constructeur qui initialise
les attributs de la classe. La méthode distance
calcule la distance entre le
point courant et un autre point passé en argument.
Pour créer une instance de la classe Point
, vous pouvez utiliser le constructeur
comme suit :
p1 = Point(0, 0)
p2 = Point(3, 4)
print(p1.distance(p2)) # 5.0
Constructeurs
Le constructeur d'une classe est une méthode spéciale appelée __init__
. Cette
méthode est appelée lors de la création d'une instance de la classe. Elle est
utilisée pour initialiser les attributs de la classe. Le premier argument de
la méthode __init__
est self
, qui est une référence à l'instance de la classe
qui est en cours de création. Les autres arguments sont les valeurs que vous
souhaitez utiliser pour initialiser les attributs de la classe.
Il n'est pas nécessaire de déclarer explicitement le constructeur dans une classe Python. Si vous ne le faites pas, Python crée un constructeur par défaut qui ne fait rien.
Contrairement à d'autres langages de programmation, Python ne permet pas de définir plusieurs constructeurs pour une classe. Cependant, vous pouvez définir des valeurs par défaut pour les arguments du constructeur pour simuler des constructeurs surchargés. Par exemples :
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
Dans cet exemple, si vous ne fournissez pas d'arguments lors de la création d'une
instance de la classe Point
, les valeurs par défaut 0
seront utilisées pour
les attributs x
et y
.
Attributs et méthodes
On appelle attributs les variables qui appartiennent à un objet. Les attributs
sont accessibles à l'aide de la notation pointée (.
). Par exemple, pour accéder
à l'attribut x
d'une instance de la classe Point
, vous pouvez utiliser p.x
.
Les méthodes sont des fonctions qui appartiennent à un objet. Elles sont définies
de la même manière que les fonctions, mais elles prennent toujours self
comme
premier argument. self
est une référence à l'instance de la classe elle-même, c'est-à-dire
l'objet sur lequel la méthode est appelée.
Par exemple, pour appeler la méthode distance
de la classe Point
, vous pouvez
utiliser p1.distance(p2)
. Notez que vous n'avez pas besoin de passer self
en
argument, Python le fait automatiquement pour vous.
En python, tous les attributs et méthodes d'une classe sont publics.
Cela signifie qu'ils peuvent être accédés et modifiés de l'extérieur de la classe.
Toutefois, la convention veut que les attributs et méthodes qui commencent par un
underscore _
soient considérés comme privés et ne doivent pas être accédés de
l'extérieur de la classe. Par exemple, vous pouvez définir un attribut privé comme
suit :
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
self._est_un_carre = x == y
Ceci n'est qu'une convention et vous pouvez toujours accéder aux attributs et méthodes privés en Python. Cependant, il est recommandé de ne pas le faire, car cela peut rendre votre code fragile et difficile à maintenir.
Accesseur et mutateur
Les accesseurs et mutateurs sont des méthodes qui permettent respectivement d'accéder et de modifier
les attributs d'une classe. Ils sont utilisés pour encapsuler les attributs et
protéger les données de la classe. En Python, il n'est pas nécessaire de définir
explicitement des accesseurs et mutateurs, car vous pouvez accéder et modifier les
attributs directement. Cependant, il est recommandé de les utiliser pour les
attributs qui doivent être protégés ou qui nécessitent une validation avant
d'être modifiés. Voici un exemple d'accesseur et de mutateur pour l'attribut x
de la
classe Point
:
class Point:
def __init__(self, x, y):
self._x = x
self._y = y
@property
def x(self):
return self._x
@x.setter
def x(self, value):
if value < 0:
raise ValueError("La coordonnée x ne peut pas être négative.")
self._x = value
@property
def y(self):
return self._y
@y.setter
def y(self, value):
if value < 0:
raise ValueError("La coordonnée y ne peut pas être négative.")
self._y = value
p = Point(3, 4)
print(p.x) # 3
p.x = 5
print(p.x) # 5
Dans cet exemple, les attributs _x
et _y
sont protégés par un accesseur et un mutateur.
En effet, selon la convention, les attributs protégés commencent par un
underscore _
. Le décorateur @property
est utilisé pour définir un accesseur et
le décorateur @x.setter
est utilisé pour définir un mutateur. Le mutateur permet
de valider la valeur avant de l'assigner à l'attribut.
Bien que l'accesseur et le mutateur soient des fonctions, ils sont
utilisés comme des attributs. Par exemple, pour accéder à l'attribut x
,
vous utilisez p.x
au lieu de p.x()
.