Sélectionnez le monde Vide, sans robots. Puis, définissez ce qui suit:
def tourne_a_droite(nom_du_robot):
for _ in range(3):
nom_du_robot.tourne_a_gauche()
Remarquez que, contrairement à ce que l’on faisait auparavant, on a la variable nom_du_robot que l’on utilise comme argument de la fonction tourne_a_droite.
Voici comment utiliser cette fonction:
Reeborg = RobotUsage()
Erdna = RobotUsage(4, 3) # crée un robot à un endroit différent!
Reeborg.avance()
tourne_a_droite(Reeborg)
Erdna.tourne_a_gauche()
tourne_a_droite(Erdna)
Faites-le!
Définissez tourne_a_droite et utilisez cette fonction dans un programme, comme nous l’avons fait ci-dessus.
Cette approche fonctionne... mais c’est bizarre d’avoir à utiliser une fonction pour faire des virages à droite et une méthode pour faire des virages à gauche. Il doit y avoir une meilleure façon ...
RobotUsage est un exemple de ce qu’on appelle une classe d’objets. Une classe est une collection d’objets qui partagent des méthodes (fonctions) ainsi que des attributs. Ci-dessous, je vais vous montrer comment créer une copie conforme d’une classe existante; après, on verra comment créer une classe qui ne sera pas identique à une classe déjà existante.
Faites ceci!
Pour créer une nouvelle classe d’objets, on utilise le mot-clé class comme ceci:
class RobotUsageClone(RobotUsage):
pass
# comme précédemment, on définit une fonction pour
# faire des virages à droite. Notez que l'indentation
# de "def" est au même niveau que celle de "class"
def tourne_a_droite(nom_du_robot):
for _ in range(3):
nom_du_robot.tourne_a_gauche()
Reeborg = RobotUsageClone()
Erdna = RobotUsageClone(4, 3)
Reeborg.avance()
tourne_a_droite(Reeborg)
Erdna.tourne_a_gauche()
tourne_a_droite(Erdna)
Cette nouvelle classe d’objets fonctionne exactement de la même façon que la classe original RobotUsage. À noter que pass est un mot-clé Python qui signifie “ne fait rien”. On l’utilise lorsqu’on veut créer un bloc de code pour respecter la syntaxe Python (l’indentation du bloc en particulier), mais qu’on n’a pas besoin que ce bloc comporte des instructions particulières.
Lorsque vous aurez reproduit l’exemple ci-dessus, ce sera le temps de créer une nouvelle classe qui fait plus que la classe originale.
Ce que j’aimerais faire, c’est de concevoir une nouvelle classe qui a une méthode appelée tourne_a_droite au lieu d’avoir à créer une fonction. Tout ce que j’ai à faire est d’insérer la définition de la fonction comme un bloc de code appartenant à la nouvelle classe (on indique ceci par l’indentation), au lieu d’une fonction séparée.
class RobotRéparé(RobotUsage):
def tourne_a_droite(nom_du_robot):
for _ in range(3):
nom_du_robot.tourne_a_gauche()
Et voici comment on peut utiliser cette nouvelle classe:
reeborg = RobotRéparé()
erdna = RobotRéparé(4, 3)
reeborg.tourne_a_gauche() # comme auparavant
reeborg.tourne_a_droite() # nouvelle méthode!
erdna.tourne_a_droite() # Ceci fonctionne aussi!
À votre tour!
Reproduisez le programme ci-dessus, et assurez-vous que le tout fonctionne correctement.
À faire
L’explication suivante repose sur un texte non encore écrit au sujet de l’utilisation de return pour les fonctions.
Nous avons vu comment on définissait et utilisait une fonction:
def ma_fonction(): # définir
...
résultat = ma_fonction() # invoquer
In l’invoquant ainsi, on associe à la variable résultat soit la valeur désignée par l’utilisation du mot-clé return ou la valeur None si return n’est pas utilisé.
La définition d’une classe d’objet et son invocation suivent le même patron:
classe MaClasse(): # définition
...
instance = MaClasse() # invocation
Par défaut, l’invocation d’une classe “retourne” automatiquement un objet sans avoir à utiliser le mot-clé return.
Si on veut qu’une classe “hérite” les méthodes et attributs d’une autre classe, il suffit d’ajouter celle-ci comme argument de la nouvelle classe:
classe Enfant(Parent):
...
Lorsqu’on invoque une méthode d’une instance donnée, Python substitue automatiquement le nom de l’instance comme premier argument de la méthode:
instance = MaClasse()
instance.ma_méthode(argument_2, argument 3, ...)
# Si ma_méthode était une fonction, on aurait plutôt écrit
# ma_méthode(instance, argument_2, argument3, ...)
Important
Les programmeurs Python suivent deux conventions importantes lors de la définition des classes et des méthodes. L’idée de ces conventions est d’être capable automatiquement de reconnaître la nature de certains objets.
Par convention, les noms de classes débutent par une lettre majuscule. Si le nom d’une classe est constitué de plusieurs mots, chaque mot débute par une lettre majuscule. Ainsi, la classe à laquelle appartient Reeborg est RobotUsage. Si on avait un nom de variable, on utiliserait plutôt des lettres minuscules et on séparerait les mots par des caractères de soulignement: robot_usage comme on l’a vu avec tourne_a_gauche.
Une deuxième convention est que le premier argument d’une méthode est désigné par le mot self (qu’on peut traduire par “soi-même”) au lieu du nom nom_du_robot que j’avais utilisé auparavant. Ainsi, pour respecter cette convention, j’aurais dû écrire plus tôt:
class RobotRéparé(RobotUsage):
def tourne_a_droite(self):
for _ in range(3):
self.tourne_a_gauche()
Si vous regardez de très près, vous pourrez peut-être constater que le mot self n’est pas écrit en noir mais plutôt en vert comme la fonction range: ceci est fait automatiquement par le logiciel qui convertit mon texte en une page web, ce logiciel reconnaissant le mot self comme étant un mot utilisé par convention en Python.