Introduction aux classes en Python


Si l'on veut créer des variables composites avec des champs nommés, il faut passer par une classe en Python 3.

Il s'agit d'un type-utilisateur que l'on définit avec le mot-clé class.

Exemple simple avec un vecteur 2D

Par exemple, si l'on veut créer un vecteur 2D v avec un champ v.x pour son abscisse et un champ v.y pour son ordonnée, alors on peut définir la classe Vector comme suit:

class Vector (object):
    __slots__= ("x", "y")

    def __init__ (self, x, y):
        self.x= x
        self.y= y

On peut alors créer autant de variables de type Vector que l'on souhaite:

v= Vector (2, 3)
w= Vector (1, 7)
print ("v.x is", v.x)
print ("w.y is", w.y) 
La sortie est alors la suivante:
v.x is 2
w.y is 7

Le tuple __slots__ permet de verrouiller les noms de champs possibles pour la classe, et ainsi éviter d'en ajouter accidentellement en faisant des fautes de frappe au clavier.

Lorsqu'un vecteur est créé par un l'appel au constructeur Vector(x,y), un objet self de type Vector est créé.

La méthode spéciale d'initialisation Vector.__init__ (self, x, y) est automatiquement invoquée, de sorte que les champs self.x et self.y sont initialisés avec les valeurs des paramètres x et y.

Ajout de méthodes à la classe

On peut rajouter ses propres méthodes à une classe. Par exemple, si l'on veut calculer la longuer d'un vecteur, on peut écrire la méthode Vector.length (self) comme ci-dessous:

import math

class Vector (object):
    __slots__= ("x", "y")

    def __init__ (self, x, y):
        self.x= x
        self.y= y

    def length (self):
        return math.sqrt (self.x * self.x + self.y * self.y)

Pour obtenir la longueur d'un vecteur v, on peut écrire Vector.length (v), ou de façon équivalente et préférée v.length():

v= Vector (2, 3)
w= Vector (1, 7)
print ("v has length", v.length()) 
print ("w has length", w.length()) 

On obtient alors la sortie:

v has length 3.605551275463989
w has length 7.0710678118654755

Mutabilité des champs des objets

Les champs des objets sont mutables (on peut changer leurs valeurs après initialisation). Par exemple, si l'on veut translater v par le vecteur de déplacement w, on peut écrire la méthode Vector.move_by (self, delta) ci-dessous, et invoquer Vector.move_by (v, w), ou de façon équivalente et de préférée v.move_by(w):

import math

class Vector (object):
    __slots__= ("x", "y")

    def __init__ (self, x, y):
        self.x= x
        self.y= y

    def length (self):
        return math.sqrt (self.x * self.x + self.y * self.y)

    def move_by (self, delta):
        self.x += delta.x
        self.y += delta.y

v= Vector (2, 3)
w= Vector (1, 7)
v.move_by (w)
print ("v is (x: %s, y: %s)" % (v.x, v.y) ) 

On obtient alors la sortie ci-dessous:

v is (x: 3, y: 10)

Représentation sous forme de chaîne de caractères

Enfin, en définissant la méthode spéciale __str__(self) qui retourne une chaîne de caractères représentant self, on peut utiliser un objet directement avec la fonction print():

import math

class Vector (object):
    __slots__= ("x", "y")

    def __init__ (self, x, y):
        self.x= x
        self.y= y

    def length (self):
        return math.sqrt (self.x * self.x + self.y * self.y)

    def move_by (self, delta):
        self.x += delta.x
        self.y += delta.y

    def __str__ (self):
        return "(%s, %s)" % (self.x, self.y)
En reprenant, l'exemple précédent, on peut maintenant écrire directement:
v= Vector (2, 3)
w= Vector (1, 7)
v.move_by (w)
print ("v is", v) 

On obtient alors la même sortie que précédemment, car v.__str__() est implicitement invoqué dans print():

v is (x: 3, y: 10)