Programmation orientée objet
Classes, instances et attributs¶
Une classe définit et nomme une structure de donnée qui vient s'ajouter aux autres structures de données du langage. Cela permet de regrouper ensemble plusieurs éléments qui ont un lien entre eux, comme on pourrait le faire avec un p-uplet nommé ou un dictionnaire. On utilise pour cela le mot clé class, suivit d'un nom commençant par une majuscule (le nom de la classe), puis des deux points. Le reste du code de la classe est indenté. La fonction __init__ (définie à l'intérieur de la classe) est appelée le constructeur de la classe. Elle permet de générer des instances (ou objet) de la classe, ici les deux variables nemo et dory.
1 2 3 4 5 6 7 8 9 10 | |
À retenir. Si le constructeur d'une classe C est du type __init__(self, arg1, arg2), on construit un nouvel élément de type C à l'aide de l'instruction C(arg1, arg2).
1 2 | |
<__main__.Poisson object at 0x7fa5f71a2dd0>
<__main__.Poisson object at 0x7fa5f72bbf70>

À retenir. Si objet est une instance de la classe C, alors il est possible d'accéder et de modifier un attribut avec la syntaxe objet.attribut (parfois appelée notation pointée).
1 2 3 4 | |
Nemo
False
True
Écrire une fonction nourrir qui prend en argument un objet p de type Poisson et qui simule l'effet d'un repas sur le poisson :
- si le poisson a faim, la poids du poisson augmente de \(1\) et le poisson n'a plus faim ;
- si le poisson n'a pas faim, rien ne se passe.
Méthodes et interface¶
Une méthode d'une classe est une fonction définie dans cette classe, qui permet de manipuler les objets de cette classe. Son premier argument est donc toujours un objet de la classe, par convention nommé self. Une méthode peut accepter un nombre quelconque de paramètres.
On appelle l'ensemble des méthodes que l'on peut appliquer à un objet l'interface de l'objet. Dans le paradigme de la programmation orientée objet, un programme qui manipule un objet n'est pas censé accéder à la totalité de son contenu (ses attributs) : il doit passer par son interface pour interagir avec lui.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 | |
Bonjour, je suis Nemo !
Bonjour, je suis Dory !
À retenir. Il est possible d'accéder aux méthodes d'une classe depuis n'importe quel objet de la classe, avec la syntaxe objet.méthode(arg1, arg2). On n'écrit pas objet.méthode(self, arg1, arg2) : le premier argument est toujours l'objet auquel la méthode s'applique.
Comment transformer la fonction
nourrirdéfinie précédemment en une méthode de la classePoisson?Écrire une méthode
est_pêchablede la classePoissonqui prend en argument un entierpoids_client(représentant le poids voulu par le client) et qui renvoieTruesi le poisson est suffisamment lourd (c'est à dire si son poids est supérieur ou égal àpoids_client), etFalsesinon.
Méthodes spéciales et erreurs¶
Méthodes spéciales¶
Certaines méthodes en python ont un rôle particulier : on les reconnaît à leur nom encadré de deux symboles _ (on les appelle parfois méthodes dunder). C'est par exemple le cas de la méthode __init__ qui est appelée automatiquement à la création d'un nouvel objet de la classe. Une fois ces méthodes définies, il est possible de les appeler avec une syntaxe plus "naturelle".
| Méthode | Appel | Description |
|---|---|---|
__str__(self) |
str(o) |
Renvoie une chaîne de caractère décrivant l'objet o |
__len__(self) |
len(o) |
Renvoie un entier définissant la taille de l'objet o |
__lt__(self, a) |
o < a |
Renvoie True si o est strictement plus petit que a |
__add__(self, a) |
o + a |
Renvoie la somme de o et a. |
Objets identiques et aliassage¶
Attention, en python les objets sont dits mutables (on peut changer les valeurs de leurs attributs). Cela mène au phénomène d'aliassage, lorsque deux variables font référence au même objet.
1 2 3 4 | |
<Poisson Dory. Poids : 16, affamé : False>
<Poisson Dory. Poids : 16, affamé : False>
Erreurs classiques¶
Attribut non définit dans la méthode __init__¶
1 | |
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [32], in <cell line: 1>()
----> 1 nemo.taille
AttributeError: 'Poisson' object has no attribute 'taille'
Confusion entre attribut et méthode¶
1 | |
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [33], in <cell line: 1>()
----> 1 nemo.poids()
TypeError: 'int' object is not callable
Confusion entre méthode et attribut¶
1 | |
<bound method Poisson.présente of <__main__.Poisson object at 0x7fa5f72ad390>>