La programmation orientée objet (POO) en Python permet de structurer le code en regroupant données et comportements dans des objets. Cette fiche vous guide à travers les bases de la POO : classes, objets, constructeurs, héritage, encapsulation, et bien plus.
📑 Sommaire
🏗️ Définir une classe
Une classe est un modèle (ou "plan") qui définit des attributs et des méthodes :
class Chien:
# Attribut de classe (partagé par toutes les instances)
espece = "Canis familiaris"
# Méthode d'instance
def aboyer(self):
print("Ouaf !")
def se_presenter(self):
print(f"Je suis un {self.espece}")
🔨 Instancier un objet
Un objet est une instance d'une classe, créée en appelant la classe comme une fonction :
# Création d'une instance
medor = Chien()
# Appel de méthodes
medor.aboyer() # Affiche : Ouaf !
medor.se_presenter() # Affiche : Je suis un Canis familiaris
# Ajout d'attributs d'instance
medor.nom = "Médor"
medor.age = 3
print(f"{medor.nom} a {medor.age} ans")
🧱 Constructeur (__init__)
La méthode __init__ est appelée lors de la création d'une instance et permet d'initialiser ses attributs :
class Chien:
def __init__(self, nom, age=1):
self.nom = nom
self.age = age
print(f"Un nouveau chien nommé {nom} a été créé !")
def info(self):
return f"{self.nom} a {self.age} ans"
# Utilisation du constructeur avec arguments
medor = Chien("Médor", 3)
rex = Chien("Rex") # Utilise la valeur par défaut pour age
print(medor.info()) # Affiche : Médor a 3 ans
print(rex.info()) # Affiche : Rex a 1 an
📐 Héritage
L'héritage permet à une classe de recevoir les attributs et méthodes d'une autre classe :
class Animal:
def __init__(self, nom):
self.nom = nom
def parler(self):
print("Je suis un animal")
class Chat(Animal): # Chat hérite d'Animal
def parler(self): # Redéfinition de la méthode
print("Miaou !")
def ronronner(self): # Nouvelle méthode
print("Ronron...")
# Utilisation
felix = Chat("Félix")
felix.parler() # Affiche : Miaou !
felix.ronronner() # Affiche : Ronron...
print(felix.nom) # Affiche : Félix (hérité d'Animal)
Appel à la méthode parente avec super() :
class Chien(Animal):
def __init__(self, nom, race):
super().__init__(nom) # Appelle le constructeur d'Animal
self.race = race
def parler(self):
super().parler() # Appelle la méthode parler d'Animal
print("Ouaf !")
rex = Chien("Rex", "Berger allemand")
rex.parler() # Affiche : Je suis un animal
# Ouaf !
🔒 Encapsulation
L'encapsulation permet de restreindre l'accès aux attributs et méthodes d'une classe :
class Compte:
def __init__(self, proprietaire, solde_initial=0):
self.proprietaire = proprietaire # Public
self.__solde = solde_initial # Privé (notation avec double underscore)
def consulter_solde(self):
return f"Solde actuel : {self.__solde}€"
def deposer(self, montant):
if montant > 0:
self.__solde += montant
return True
return False
def retirer(self, montant):
if 0 < montant <= self.__solde:
self.__solde -= montant
return True
return False
# Utilisation
compte = Compte("Guillaume", 1000)
print(compte.consulter_solde()) # Affiche : Solde actuel : 1000€
compte.deposer(500)
print(compte.consulter_solde()) # Affiche : Solde actuel : 1500€
# Tentative d'accès direct à l'attribut privé
# print(compte.__solde) # Génère une erreur AttributeError
# Python permet tout de même d'y accéder avec une notation spéciale (à éviter)
print(compte._Compte__solde) # Affiche : 1500
🔄 Méthodes spéciales
Python offre des méthodes spéciales (commençant et finissant par double underscore) pour personnaliser le comportement des objets :
class Vecteur:
def __init__(self, x, y):
self.x = x
self.y = y
# Représentation pour str()
def __str__(self):
return f"Vecteur({self.x}, {self.y})"
# Représentation pour repr()
def __repr__(self):
return f"Vecteur({self.x}, {self.y})"
# Addition de vecteurs
def __add__(self, autre):
return Vecteur(self.x + autre.x, self.y + autre.y)
# Comparaison d'égalité
def __eq__(self, autre):
return self.x == autre.x and self.y == autre.y
# Obtenir la longueur du vecteur avec len()
def __len__(self):
import math
return math.floor(math.sqrt(self.x**2 + self.y**2))
# Utilisation
v1 = Vecteur(3, 4)
v2 = Vecteur(1, 1)
print(v1) # Affiche : Vecteur(3, 4)
print(v1 + v2) # Affiche : Vecteur(4, 5)
print(v1 == v2) # Affiche : False
print(len(v1)) # Affiche : 5
🎁 Bonus : Techniques avancées
Méthodes de classe et méthodes statiques
class MaClasse:
compteur = 0 # Variable de classe
def __init__(self):
MaClasse.compteur += 1
# Méthode de classe (accès aux attributs de classe)
@classmethod
def get_compteur(cls):
return f"Nombre d'instances : {cls.compteur}"
# Méthode statique (indépendante de la classe)
@staticmethod
def info():
return "Cette classe est un exemple."
# Utilisation
obj1 = MaClasse()
obj2 = MaClasse()
print(MaClasse.get_compteur()) # Affiche : Nombre d'instances : 2
print(MaClasse.info()) # Affiche : Cette classe est un exemple.
Propriétés (@property)
class Personne:
def __init__(self, nom, age):
self._nom = nom
self._age = age
# Getter pour age
@property
def age(self):
return self._age
# Setter pour age
@age.setter
def age(self, valeur):
if 0 <= valeur <= 150:
self._age = valeur
else:
raise ValueError("Age invalide")
# Getter pour nom
@property
def nom(self):
return self._nom.title()
# Utilisation
p = Personne("jean", 30)
print(p.nom) # Affiche : Jean (avec majuscule)
print(p.age) # Affiche : 30
p.age = 31 # Utilise le setter
print(p.age) # Affiche : 31
# p.age = 200 # Génère une erreur ValueError