Classes et objets Python
Apprenez comment les classes et objets Python fonctionnent : définir des classes, utiliser __init__, créer des instances, travailler avec des attributs et des méthodes, et comprendre l'héritage.
Python est un langage de programmation orientée objet (POO), ce qui signifie qu'il organise le code autour d'objets plutôt que de simples fonctions. Une classe est le modèle qui décrit les données qu'un objet contient et ce qu'il peut faire. Un objet est une instance spécifique créée à partir de ce modèle.
Ce chapitre couvre :
- Ce que sont les classes et les objets, et pourquoi ils importent
- Définir une classe avec
__init__, les attributs d'instance et les méthodes - Les attributs de classe par rapport aux attributs d'instance
- Créer et utiliser des objets
- Modifier et supprimer des attributs
- Vérifier les types d'objets avec
isinstance() - Une première approche de l'héritage
Pour approfondir l'héritage, voir Python Inheritance. Pour des modèles de POO plus avancés, voir Python Abstract Base Classes.
Qu'est-ce qu'une classe ?
Pensez à une classe comme à un emporte-pièce et à un objet comme au biscuit. Vous définissez la forme une seule fois (la classe), puis vous découpez autant de biscuits (objets) que vous en avez besoin. Chaque objet partage la même structure mais contient ses propres données.
class Dog:
pass # an empty class — valid but not very useful yetLe mot-clé class suivi d'un nom et d'un deux-points crée une nouvelle classe. Par convention, les noms de classes utilisent le style CapWords (aussi appelé PascalCase) : MyClass, BankAccount, HttpRequest.
La méthode __init__
La méthode __init__ (abréviation d'initialise) s'exécute automatiquement chaque fois que vous créez un nouvel objet. Elle configure l'état initial de l'objet en assignant des valeurs à ses attributs d'instance.
class Dog:
def __init__(self, name, age):
self.name = name # instance attribute
self.age = age # instance attributeLe premier paramètre est toujours self — il fait référence à l'objet en cours de création. Python le passe automatiquement ; vous ne le fournissez jamais vous-même.
Attributs d'instance vs. attributs de classe
| Type | Défini dans | Appartient à | Partagé ? |
|---|---|---|---|
| Attribut d'instance | __init__ (via self) | Chaque objet | Non — chaque objet a sa propre copie |
| Attribut de classe | Corps de la classe (en dehors de toute méthode) | La classe elle-même | Oui — tous les objets partagent une seule copie |
class Dog:
species = "Canis familiaris" # class attribute — shared by all Dogs
def __init__(self, name, age):
self.name = name # instance attribute
self.age = age # instance attribute
fido = Dog("Fido", 3)
bella = Dog("Bella", 5)
print(fido.species) # Canis familiaris
print(bella.species) # Canis familiaris (same class attribute)
print(fido.name) # Fido
print(bella.name) # Bella (different instance attributes)Utilisez un attribut de classe lorsqu'une valeur est identique pour chaque objet de ce type (par exemple, l'espèce de tous les chiens). Utilisez des attributs d'instance pour les données qui varient par objet.
Définir des méthodes
Une méthode est une fonction définie à l'intérieur d'une classe. Comme __init__, elle prend toujours self comme premier paramètre afin de pouvoir accéder aux attributs propres de l'objet.
class Dog:
species = "Canis familiaris"
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
return f"{self.name} says: Woof!"
def description(self):
return f"{self.name} is {self.age} years old."Vous appelez une méthode sur un objet en utilisant la notation pointée — Python passe automatiquement l'objet en tant que self :
fido = Dog("Fido", 3)
print(fido.bark()) # Fido says: Woof!
print(fido.description()) # Fido is 3 years old.La méthode __str__
Python appelle __str__ lorsque vous passez un objet à print() ou str(). Sans elle, vous obtenez une adresse peu utile comme <__main__.Dog object at 0x...>. La définir facilite grandement le débogage.
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Dog(name={self.name!r}, age={self.age})"
fido = Dog("Fido", 3)
print(fido) # Dog(name='Fido', age=3)Créer et utiliser des objets
Créer un objet s'appelle l'instanciation. Vous appelez la classe comme une fonction, en passant les arguments que __init__ attend (sauf self) :
Vous pouvez créer autant d'objets que nécessaire à partir de la même classe — chacun est indépendant :
class Rectangle:
def __init__(self, width, height=1):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
r1 = Rectangle(4, 3)
r2 = Rectangle(5) # height defaults to 1
print(r1.area()) # 12
print(r1.perimeter()) # 14
print(r2.area()) # 5Notez que height=1 fournit une valeur par défaut : si vous omettez le second argument, Python utilise 1 automatiquement.
Modifier et supprimer des attributs
Vous pouvez modifier ou ajouter des attributs sur un objet après sa création, et les supprimer avec del :
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30)
print(p.age) # 30
p.age = 31 # modify an existing attribute
print(p.age) # 31
p.email = "[email protected]" # add a new attribute at runtime
print(p.email) # [email protected]
del p.email # delete the attribute
# print(p.email) # would raise AttributeErrorBien que Python permette d'ajouter librement des attributs, il est plus propre de déclarer tous les attributs dans __init__ pour que la structure de la classe soit évidente au premier coup d'œil.
Vérifier les types d'objets
Utilisez isinstance() pour vérifier si un objet est une instance d'une classe particulière. Elle retourne True pour la classe elle-même et pour n'importe laquelle de ses classes parentes :
class Animal:
pass
class Dog(Animal):
pass
rex = Dog()
print(isinstance(rex, Dog)) # True
print(isinstance(rex, Animal)) # True — Dog is a subclass of Animal
print(type(rex) is Dog) # True
print(type(rex) is Animal) # False — type() does not climb the hierarchyPréférez isinstance() à type() is dans la plupart du code car elle gère correctement les sous-classes.
Une première approche de l'héritage
L'héritage permet à une nouvelle classe de réutiliser et d'étendre le comportement d'une classe existante. La nouvelle classe (enfant ou sous-classe) acquiert automatiquement tous les attributs et méthodes du parent :
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound."
class Dog(Animal):
def speak(self): # override the parent method
return f"{self.name} says: Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says: Meow!"
dog = Dog("Rex")
cat = Cat("Whiskers")
print(dog.speak()) # Rex says: Woof!
print(cat.speak()) # Whiskers says: Meow!
print(isinstance(dog, Animal)) # TrueDog et Cat héritent toutes deux de __init__ de Animal, donc elles n'ont pas besoin de le répéter. Elles ne redéfinissent que speak() pour fournir un comportement spécifique à la race.
Pour un traitement complet de l'héritage — incluant super(), l'héritage multiple et l'ordre de résolution des méthodes — voir Python Inheritance.
Quand utiliser une classe ?
Les classes ont le plus de sens lorsque :
- Vous avez des données et un comportement qui vont ensemble (un compte bancaire qui sait comment déposer et retirer de l'argent).
- Vous avez besoin de plusieurs objets indépendants du même type (plusieurs objets
Dog, chacun avec des noms et des âges différents). - Vous voulez modéliser des entités du monde réel avec une identité claire.
Les simples fonctions utilitaires qui transforment simplement une entrée en sortie sont souvent mieux en tant que fonctions ordinaires. Python n'exige pas que tout soit dans une classe.
Résumé
| Concept | Ce qu'il fait |
|---|---|
class | Définit un nouveau type |
__init__ | Initialise les attributs d'instance lors de la création d'un objet |
self | Fait référence à l'objet courant à l'intérieur d'une méthode |
| Attribut d'instance | Donnée appartenant à un objet spécifique |
| Attribut de classe | Donnée partagée par tous les objets de la classe |
| Méthode | Une fonction définie à l'intérieur d'une classe ; reçoit toujours self |
__str__ | Contrôle comment print() affiche l'objet |
isinstance() | Vérifie si un objet est une instance d'une classe ou de ses sous-classes |
| Héritage | Permet à une classe enfant de réutiliser et d'étendre une classe parente |