Module 3Appliquer la POO en Python
Chapitre 7 sur 10
Implémenter une classe en Python
Écrire des classes complètes en Python et appliquer les quatre piliers sur une application bancaire.
- ≈ 110 min
- 4 leçons
- 4 vidéos
- 2 exercices
Module 3Appliquer la POO en Python
Chapitre 7 sur 10
Écrire des classes complètes en Python et appliquer les quatre piliers sur une application bancaire.
Objectifs
Avec ce chapitre, tu sauras…
__init__ et ses méthodes ;self ;@classmethod et @staticmethod ;__str__, __repr__, __eq__, __lt__ ;Ce chapitre rassemble toute la POO en Python. Le fil rouge est la gestion de comptes bancaires : à la fin, tu auras une petite application complète.
Leçon 1
class Compte:
"""Un compte bancaire.""" # docstring de la classe
taux_frais = 0.01 # attribut de classe
def __init__(self, numero, titulaire, solde=0): # constructeur
self.numero = numero # attributs d'instance
self.titulaire = titulaire
self.solde = solde
def deposer(self, montant): # méthode d'instance
self.solde += montant
compte = Compte("MA001", "Sara", 1000) # instanciation : appel de __init__
compte.deposer(250) # équivaut à Compte.deposer(compte, 250)
print(compte.solde) # 1250Vidéo · À regarder
FRApprendre la Programmation Orientée Objets (POO) Python
MaxCode · YouTube
Vidéo · À regarder
FRPython - Cours complet pour débutants (2026)
SimpleTech par Sergio · YouTube
Leçon 2
| Sorte | Décorateur | Premier paramètre | Accès |
|---|---|---|---|
| d'instance | aucun | self (l'objet) | attributs de l'objet et de la classe |
| de classe | @classmethod | cls (la classe) | attributs de classe ; crée des instances |
| statique | @staticmethod |
Leçon 3
| Méthode | Appelée par | Rôle |
|---|---|---|
__init__(self, ...) | Compte(...) | initialiser l'objet |
__str__(self) | print(obj), str(obj) | texte lisible pour l'utilisateur |
__repr__(self) | l'interpréteur, repr(obj) | texte précis pour le développeur |
__eq__(self, autre) |
Leçon 4
| Pilier | Dans le code |
|---|---|
| abstraction | Compte(ABC) et la méthode abstraite solde_disponible() |
| encapsulation | __numero privé, _solde protégé, accès par @property, contrôles dans deposer() / retirer() |
| héritage | CompteCourant(Compte), CompteEpargne(Compte), super().__init__() |
| polymorphisme | retirer() appelle solde_disponible() de la classe réelle ; print(c) appelle le bon __str__ |
1self désigne…
2Le constructeur Python s'appelle…
3Une méthode qui reçoit la classe en premier paramètre est décorée par…
4print(obj) appelle…
5Pour que sorted() fonctionne sur tes objets, tu définis…
6super().__init__(...) sert à…
L'essentiel du chapitre
class Nom: ; constructeur __init__(self, ...) ; self = l'objet ; self.attribut = attribut d'instance.self), de classe (@classmethod, cls), statiques (@staticmethod).__str__, __repr__, __eq__, __lt__, __len__, __add__.ABC/@abstractmethod (abstraction), __attr/@property (encapsulation), class Fille(Mere) + super() (héritage), redéfinition + liaison dynamique (polymorphisme).client.comptes).| rien de particulier : une fonction rangée dans la classe |
Vidéo · À regarder
FRApprendre la Programmation Orientée Objets (POO) Python
MaxCode · YouTube
a == b| égalité |
__lt__(self, autre) | a < b, sorted() | comparaison (implémente « Comparable ») |
__len__(self) | len(obj) | longueur |
__add__(self, autre) | a + b | addition |
__del__(self) | destruction de l'objet | destructeur (rarement utilisé) |
un Client contient une liste de Compte |
Vidéo · À regarder
FRApprendre la Programmation Orientée Objets (POO) Python
MaxCode · YouTube
Créer une classe, puis la méthode __init__ : la base de tout ce chapitre, en français.
L'introduction aux classes du cours de SimpleTech par Sergio, pour une deuxième explication.
class Compte:
nombre_comptes = 0
def __init__(self, numero, solde=0):
self.numero = numero
self.solde = solde
Compte.nombre_comptes += 1
def afficher(self): # méthode d'instance : reçoit l'objet
print(self.numero, self.solde)
@classmethod
def depuis_texte(cls, texte): # méthode de classe : reçoit la classe
numero, solde = texte.split(";")
return cls(numero, float(solde)) # un « constructeur alternatif »
@staticmethod
def est_numero_valide(numero): # méthode statique : ne reçoit rien
return numero.startswith("MA") and len(numero) == 5
c = Compte.depuis_texte("MA002;500")
print(Compte.nombre_comptes, Compte.est_numero_valide("MA002")) # 1 TrueLes méthodes spéciales (ou « dunder », pour double underscore) permettent à tes objets de se comporter comme les types intégrés.
from abc import ABC, abstractmethod
class Compte(ABC): # ABSTRACTION
"""Compte bancaire abstrait."""
def __init__(self, numero, solde=0):
self.__numero = numero # ENCAPSULATION : privé
self._solde = solde # protégé : accessible aux filles
@property
def numero(self):
return self.__numero
@property
def solde(self):
return self._solde
def deposer(self, montant):
if montant <= 0:
raise ValueError("Montant invalide.")
self._solde += montant
def retirer(self, montant):
if montant <= 0:
raise ValueError("Montant invalide.")
if montant > self.solde_disponible():
raise ValueError("Solde insuffisant.")
self._solde -= montant
@abstractmethod
def solde_disponible(self): # chaque type de compte la définit
pass
def __str__(self):
return f"{type(self).__name__} {self.numero} : {self._solde:.2f} DH"
class CompteCourant(Compte): # HÉRITAGE
def __init__(self, numero, solde=0, decouvert=1000):
super().__init__(numero, solde)
self.decouvert = decouvert
def solde_disponible(self): # implémentation
return self._solde + self.decouvert
class CompteEpargne(Compte):
def __init__(self, numero, solde=0, taux=0.03):
super().__init__(numero, solde)
self.taux = taux
def solde_disponible(self):
return self._solde # pas de découvert
def ajouter_interets(self):
self._solde += self._solde * self.taux
def __str__(self): # REDÉFINITION
return super().__str__() + f" (taux {self.taux:.0%})"class Client:
def __init__(self, nom):
self.nom = nom
self.comptes = [] # un client A DES comptes
def ajouter_compte(self, compte):
self.comptes.append(compte)
def patrimoine(self):
return sum(c.solde for c in self.comptes)
def __str__(self):
lignes = [f"Client : {self.nom}"]
lignes += [f" - {c}" for c in self.comptes] # POLYMORPHISME : chaque __str__
lignes.append(f" Patrimoine : {self.patrimoine():.2f} DH")
return "\n".join(lignes)from banque.compte import CompteCourant, CompteEpargne
from banque.client import Client
sara = Client("Sara Benali")
cc = CompteCourant("MA001", 500)
ce = CompteEpargne("MA002", 10000)
sara.ajouter_compte(cc)
sara.ajouter_compte(ce)
cc.retirer(1200) # autorisé grâce au découvert : solde = -700
ce.ajouter_interets() # 10000 + 3 % = 10300
print(sara)Client : Sara Benali
- CompteCourant MA001 : -700.00 DH
- CompteEpargne MA002 : 10300.00 DH (taux 3%)
Patrimoine : 9600.00 DHTableau: Où est chaque pilier ?
Modélise une médiathèque : une classe abstraite Document (titre, année, méthode abstraite duree_pret()), deux sous-classes Livre (21 jours) et DVD (7 jours), et une classe Mediatheque qui contient une liste de documents, permet d'en ajouter et affiche tous les documents triés par année.
Écris une classe Rectangle avec longueur et largeur (refusant les valeurs négatives grâce à des propriétés), des méthodes surface() et perimetre(), une méthode statique est_carre(l, L), une méthode de classe carre(cote) qui crée un carré, et __str__, __eq__ (même surface).
Les méthodes de classe, puis un parallèle avec les variables, en français.
class Compte:
def __init__(self, numero, solde):
self.numero = numero
self.solde = solde
def __str__(self):
return f"Compte {self.numero} : {self.solde:.2f} DH"
def __repr__(self):
return f"Compte({self.numero!r}, {self.solde!r})"
def __eq__(self, autre):
return self.numero == autre.numero
def __lt__(self, autre):
return self.solde < autre.solde
comptes = [Compte("MA001", 300), Compte("MA002", 100)]
print(comptes[0]) # Compte MA001 : 300.00 DH
print(sorted(comptes)) # trié par solde grâce à __lt__L'exercice pratique de la vidéo POO de MaxCode : fais-le avant de regarder la solution.