You are here: Sommaire > Plongez au coeur de Python > Les objets et l'orienté objet > Définition de classes | << >> | ||||
Plongez au coeur de PythonDe débutant à expert |
Python est entièrement orienté objet : vous pouvez définir vos propres classes, hériter de vos classes ou des classes prédéfinies et instancier les classes que vous avez défini.
Définir une classe en Python est simple, comme pour les fonctions, il n'y a pas de définition séparée d'interface. Vous définissez simplement la classe et commencez à coder. Une classe Python commence par le mot réservé class suivi du nom de la classe. Techiquement c'est tout ce qui est requis, une classe n'hérite pas obligatoirement d'une autre.
class Loaf: pass
L'instruction pass de Python est comme une paire d'accolades vide ({}) en Java ou C. |
Bien sûr, dans des cas réels la plupart des classes hériteront d'autres classes et elles définiront leurs propres classes, méthodes et attributs. Mais comme vous l'avez vu, il n'y a rien qu'une classe doit absolument avoir en dehors d'un nom. En particulier, les programmeurs C++ s'étonneront sans doute que les classes Python n'aient pas de constructeurs et de destructeurs explicites. Les classes Python ont quelque chose de semblable à un constructeur : la méthode __init__.
from UserDict import UserDict class FileInfo(UserDict):
En Python, l'ancêtre d'une classe est simplement indiqué entre parenthèses immédiatement après le nom de la classe. La classe FileInfo est hérite donc de la classe UserDict (qui a été importée du module UserDict). UserDict est une classe qui se comporte comme un dictionnaire, vous permettant pratiquement de dériver le type de données dictionnaire et d'y ajouter votre propre comportement (il y a des classes semblables UserList et UserString qui vous permettent de dériver les listes et les chaînes). Il y a un peu de magie noire derrière tout cela, nous la démystifierons plus loin dans ce chapitre lorsque nous explorerons la classe UserDict plus en détail. |
En Python, l'ancêtre d'une classe est simplement indiqué entre parenthèses immédiatement après le nom de la classe. Il n'y a pas de mot clé spécifique comme extends en Java. |
Python supporte l'héritage multiple. Entre les parenthèses qui suivent le nom de classe, vous pouvez indiquer autant de classes ancêtres que vous le souhaitez, séparées par des virgules.
Cet exemple montre l'initialisation de la classe FileInfo avec la méthode __init__.
class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None):
Les classes peuvent aussi (et le devraient) avoir une docstring, comme les modules et les fonctions. | |
__init__ est appelé immédiatement après qu'une instance de la classe est créée. Il serait tentant mais incorrect de l'appeler le constructeur de la classe. Tentant, parceque ça ressemble à un constructeur (par convention, __init__ est la première méthode définie de la classe), ça se comporte comme un constructeur (c'est le premier morceau de code exécuté dans une nouvelle instance de la classe) et que ça sonne pareil («init» fait penser à quelque chose comme un constructeur). Incorrect, parce qu'au moment ou __init__ est appelé, l'objet à déjà été créé et qu vous avez déjà une référence valide à la nouvelle instance de la classe. Mais __init__ est ce qui se rapproche le plus d'un constructeur en Python et remplit en gros le même rôle. | |
Le premier argument de chaque méthode de classe, y compris __init__, est toujours une référence à l'instance actuelle de la classe. Par convention, cet argument est toujours nommé self. Dans la méthode __init__, self fait référence à l'objet nouvellement créé, dans les autres méthodes de classe, il fait référence à l'instance dont la méthode a été appelée. Bien que vous deviez spécifier self explicitement lorsque vous définissez la méthode, vous ne devez pas le spécifier lorsque vous appelez la méthode, Python l'ajoutera pour vous automatiquement. | |
Une méthode __init__ peut prendre n'importe quel nombre d'arguments et tout comme pour les fonctions, les arguments peuvent être définis avec des valeurs par défaut, ce qui les rend optionnels lors de l'appel. Ici filename a une valeur par défaut de None, la valeur nulle de Python. |
Par convention, le premier argument d'une méthode de classe (la référence à l'instance en cours) est appelé self. Cet argument remplit le rôle du mot réservé this en C++ ou Java, mais self n'est pas un mot réservé de Python, seulement une convention de nommage. Cependant, veuillez ne pas l'appeler autre chose que self, c'est une très forte convention. |
class FileInfo(UserDict): "store file metadata" def __init__(self, filename=None): UserDict.__init__(self) self["name"] = filename
Lorsque vous définissez vos méthodes de classe, vous devez indiquer explicitement self comme premier argument de chaque méthode, y compris __init__. Quand vous appelez une méthode d'une classe ancêtre depuis votre classe, vous devez inclure l'argument self. Mais quand vous appelez votre méthode de classe de l'extérieur, vous ne spécifiez rien pour l'argument self, vous l'omettez complètement et Python ajoute automatiquement la référence d'instance. Je me rends bien compte qu'on s'y perd au début, ce n'est pas réellement incohérent même si cela peut sembler l'être car cela est basé sur une distinction (entre méthode liée et non liée) que vous ne connaissez pas pour l'instant.
Ouf. Je sais bien que ça fait beaucoup à absorber, mais vous ne tarderez pas à comprendre tout ça. Toutes les classes Python fonctionnent de la même manière, donc quand vous en avez appris une, vous les connaissez toutes. Mais même si vous oubliez tout le reste souvenez vous de ça, car ça vous jouera des tours :
Les méthodes __init__ sont optionnelles, mais quand vous en définissez une, vous devez vous rappeler d'appeler explicitement la méthode __init__ de l'ancêtre de la classe. C'est une règle plus générale : quand un descendant veut étendre le comportement d'un ancêtre, la méthode du descendant doit appeler la méthode de l'ancêtre explicitement au moment approprié, avec les arguments appropriés. |
<< Importation de modules avec from module import |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
Instantiation de classes >> |