Numérique et sciences informatiques (spécialité) · TerminaleBac
Programmation orientée objet : exercices corrigés de Terminale NSI
Publié le 7 novembre 2026 · Mis à jour le 7 novembre 2026 · Signaler une erreur
L'essentiel
- Une classe est le modèle ; un objet est un exemplaire créé à partir de ce modèle, avec ses propres valeurs d'attributs.
- Le constructeur
__init__fixe l'état initial ; les méthodes décrivent le comportement et reçoiventselfen premier paramètre. - Deux variables peuvent désigner le même objet : une modification faite par l'une se voit aussi par l'autre.
- Pour modéliser, cherche d'abord ce que l'objet sait (attributs) et ce qu'il fait (méthodes).
- Pour tracer un programme, suis l'état de chaque objet ligne après ligne dans un tableau.
Comment utiliser ces exercices
Ces exercices te font manipuler la programmation orientée objet en Python, comme au programme de la spécialité NSI en Terminale. Cette façon de programmer consiste à définir des briques logicielles, les objets, et à faire interagir ces objets entre eux 3. Un objet regroupe des informations et des mécanismes qui concernent un même sujet 4. Les exercices avancent par difficulté croissante : lecture de code, écriture de méthodes, puis modélisation.
Les exercices
Exercice 1 Lire une classe : le compte bancaire
On considère la classe suivante.
class Compte:
def __init__(self, solde):
self.solde = solde
def deposer(self, somme):
self.solde = self.solde + somme
def retirer(self, somme):
if somme <= self.solde:
self.solde = self.solde - somme
On exécute :
c = Compte(100)
c.deposer(50)
c.retirer(200)
c.retirer(30)
- Quel est le rôle de
__init__ici ? - Quelle est la valeur de
c.soldeà la fin ?
Indice 1
Regarde la condition dans retirer : que se passe-t-il quand la somme dépasse le solde ?
Indice 2
Fais un petit tableau avec le solde après chaque ligne.
Voir la correction pas à pas
__init__est le constructeur : il est appelé quand on écritCompte(100)et il donne à l'objet son attributsolde, ici égal à 100.Après
Compte(100), le solde vaut 100.Après
c.deposer(50), le solde vaut 100 + 50 = 150.Pour
c.retirer(200), la condition200 <= 150est fausse : rien n'est modifié, le solde reste 150.Pour
c.retirer(30), la condition30 <= 150est vraie : le solde devient 150 - 30 = 120.
Le solde final est 120. Une méthode peut refuser de modifier l'objet : c'est un moyen de protéger la cohérence de son état.
Exercice 2 Suivre l'état d'un compteur
class Compteur:
def __init__(self, depart, pas):
self.valeur = depart
self.pas = pas
def incrementer(self):
self.valeur = self.valeur + self.pas
c = Compteur(2, 3)
for i in range(5):
c.incrementer()
Quelle est la valeur de c.valeur après la boucle ? Que vaut c.pas ?
Indice 1
La boucle appelle la méthode combien de fois ?
Indice 2
À chaque appel, l'attribut valeur augmente de la même quantité.
Voir la correction pas à pas
À la création,
c.valeurvaut 2 etc.pasvaut 3.range(5)répète l'appelc.incrementer()cinq fois.Chaque appel ajoute 3 : les valeurs successives sont 5, 8, 11, 14, 17.
Aucune ligne ne modifie
pas: il reste à 3.
c.valeur vaut 17 et c.pas vaut 3. Un attribut garde sa valeur entre deux appels de méthode : c'est ce qui distingue un objet d'une simple variable locale.
Exercice 3 Écrire une classe Rectangle
Écris une classe Rectangle dont le constructeur prend une largeur et une hauteur, avec deux méthodes aire() et perimetre() qui renvoient respectivement l'aire et le périmètre.
On crée ensuite r = Rectangle(7, 4). Quelle valeur renvoie r.aire() ?
Indice 1
Les attributs se créent dans __init__ avec self..
Indice 2
Une méthode qui renvoie un résultat utilise return.
Voir la correction pas à pas
Commence par le constructeur : il reçoit deux paramètres et les range dans deux attributs de l'objet, grâce à
self..Ajoute ensuite la méthode d'aire : elle multiplie les deux attributs et renvoie le produit, avec
return self.largeur * self.hauteur.Ajoute la méthode de périmètre : elle renvoie
2 * (self.largeur + self.hauteur).Assemble le tout, par exemple :
class Rectangle: def __init__(self, a, b): self.largeur = a self.hauteur = b def aire(self): return self.largeur * self.hauteur def perimetre(self): return 2 * (self.largeur + self.hauteur)Pour
Rectangle(7, 4), l'aire vaut 7 × 4 = 28.
r.aire() renvoie 28. Les méthodes n'ont pas besoin qu'on leur repasse les dimensions : elles les lisent dans l'objet via self.
Exercice 4 Deux noms, un seul objet
class Panier:
def __init__(self):
self.articles = []
def ajouter(self, nom):
self.articles.append(nom)
a = Panier()
a.ajouter("pomme")
b = a
b.ajouter("poire")
c = Panier()
c.ajouter("kiwi")
- Combien d'articles contient
a.articles? Etc.articles? - Quelle est la valeur de
len(a.articles) + len(c.articles)? - Que faudrait-il changer pour que
bsoit un panier indépendant dea?
Indice 1
Que fait l'instruction b = a : crée-t-elle un nouvel objet ?
Indice 2
Quelle ligne crée réellement un nouvel objet de la classe ?
Voir la correction pas à pas
Après
a = Panier()puisa.ajouter("pomme"), le panier deacontient « pomme ».b = ane crée aucun objet :best un second nom pour le même panier quea.b.ajouter("poire")modifie donc le panier commun :a.articlescontient « pomme » et « poire », soit 2 articles.c = Panier()crée un autre objet, avec sa propre liste vide ; après l'ajout,c.articlescontient 1 article (« kiwi »).La somme vaut 2 + 1 = 3.
Pour avoir un panier indépendant, il faut écrire
b = Panier(): seul un appel à la classe crée un nouvel objet.
La somme vaut 3. Retiens que l'affectation entre deux variables copie une référence, pas l'objet ; seul Classe(...) fabrique un nouvel exemplaire.
Exercice 5 Calculer une moyenne avec une méthode
class Eleve:
def __init__(self, nom):
self.nom = nom
self.notes = []
def ajouter_note(self, note):
self.notes.append(note)
def moyenne(self):
return sum(self.notes) / len(self.notes)
On exécute :
e = Eleve("Lina")
e.ajouter_note(12)
e.ajouter_note(15)
e.ajouter_note(9)
- Que renvoie
e.moyenne()? - Quelle erreur se produit si on appelle
moyenne()sur un élève qui n'a aucune note ? Propose une correction.
Indice 1
sum additionne tous les éléments d'une liste.
Indice 2
Que vaut len([]) ?
Voir la correction pas à pas
La liste des notes est
[12, 15, 9].La somme vaut 12 + 15 + 9 = 36 et la liste contient 3 notes.
La moyenne est 36 / 3 = 12.
Sans note,
len(self.notes)vaut 0 et la division par 0 provoque une erreurZeroDivisionError.Correction possible : tester d'abord
if len(self.notes) == 0:et renvoyerNone(ou lever une erreur explicite) avant de diviser.
e.moyenne() renvoie 12. Une bonne méthode prévoit les états limites de l'objet, ici une liste vide.
Exercice 6 Total d'une liste d'objets
class Produit:
def __init__(self, nom, prix, quantite):
self.nom = nom
self.prix = prix
self.quantite = quantite
def cout(self):
return self.prix * self.quantite
stock = [Produit("cahier", 2.5, 4),
Produit("calculatrice", 10, 1),
Produit("stylo", 1.2, 5)]
total = 0
for p in stock:
total = total + p.cout()
- Calcule le coût de chaque produit.
- Quelle est la valeur finale de
total? - Écris une instruction qui construit la liste des noms des produits dont le coût dépasse 8.
Indice 1
Appelle mentalement cout() sur chaque objet de la liste.
Indice 2
Pour la question 3, pense à une liste en compréhension avec une condition.
Voir la correction pas à pas
Cahier : 2,5 × 4 = 10.
Calculatrice : 10 × 1 = 10.
Stylo : 1,2 × 5 = 6.
La boucle additionne les trois coûts : 10 + 10 + 6 = 26.
Pour la liste des noms :
[p.nom for p in stock if p.cout() > 8]; elle contient « cahier » et « calculatrice ».
total vaut 26. Chaque objet de la liste sait calculer son propre coût : la boucle n'a pas besoin de connaître les détails.
Exercice 7 Additionner deux fractions avec un objet
class Fraction:
def __init__(self, num, den):
self.num = num
self.den = den
def additionner(self, autre):
n = self.num * autre.den + autre.num * self.den
d = self.den * autre.den
return Fraction(n, d)
def valeur(self):
return self.num / self.den
f = Fraction(1, 4)
g = Fraction(1, 6)
h = f.additionner(g)
- Quels sont les attributs de
h? - Les objets
fetgont-ils été modifiés par l'appel ? - Donne la valeur décimale renvoyée par
h.valeur(), arrondie à 10 chiffres après la virgule.
Indice 1
Dans additionner, quelle instruction fabrique un nouvel objet ?
Indice 2
Applique la formule de la méthode sans simplifier la fraction.
Voir la correction pas à pas
Dans la méthode,
selfdésignef(1/4) etautredésigneg(1/6).Le numérateur calculé est 1 × 6 + 1 × 4 = 10.
Le dénominateur calculé est 4 × 6 = 24.
La méthode renvoie
Fraction(10, 24):h.numvaut 10 eth.denvaut 24 (la fraction n'est pas simplifiée).fetgne sont pas modifiés : la méthode ne fait aucune affectation surself.numni surautre.num, elle construit un nouvel objet.h.valeur()renvoie 10 / 24 = 0,4166666667 (arrondi).
La valeur est environ 0,4166666667. Une méthode peut soit modifier l'objet courant, soit renvoyer un nouvel objet : ici, f et g restent intacts.
Exercice 8 Modéliser une bibliothèque
Un lycée veut gérer les prêts de livres de son CDI. La programmation orientée objet demande une étape de modélisation : on décide quels objets représenter et comment ils interagissent 3.
- Propose une classe
Livreavec au moins trois attributs et une méthode qui indique si le livre est disponible. - Propose une classe
Emprunteuret une méthodeemprunter(livre). - Que doit faire
empruntersi le livre est déjà prêté ? - Écris le code Python de l'ensemble.
Indice 1
Demande-toi pour chaque classe : que sait l'objet (attributs) ? Que sait-il faire (méthodes) ?
Indice 2
Un livre peut avoir un attribut booléen qui change quand il est prêté.
Voir la correction pas à pas
Pour
Livre, on retient le titre, l'auteur et un booléendisponibleinitialisé àTrue, plus une méthodeest_disponible()qui renvoie ce booléen.Pour
Emprunteur, on retient le nom et la liste des livres actuellement empruntés, vide au départ.La méthode
emprunterdoit d'abord testerlivre.disponible; si le livre est disponible, elle l'ajoute à la liste de l'emprunteur et passelivre.disponibleàFalse.Si le livre n'est pas disponible, la méthode ne modifie rien et renvoie
Falsepour signaler l'échec (elle renvoieTrueen cas de succès).Code possible :
class Livre: def __init__(self, titre, auteur): self.titre = titre self.auteur = auteur self.disponible = True def est_disponible(self): return self.disponible class Emprunteur: def __init__(self, nom): self.nom = nom self.livres = [] def emprunter(self, livre): if livre.disponible: self.livres.append(livre) livre.disponible = False return True return False
Il n'y a pas une seule bonne modélisation : l'essentiel est que chaque classe regroupe des données et les actions qui les concernent, et que les objets interagissent par leurs méthodes. Ici, Emprunteur agit sur un Livre qu'on lui passe en paramètre.
Les questions qu'on se pose
Quelle différence entre une classe et un objet ?
La classe est un modèle : elle décrit les caractéristiques et les comportements communs. Un objet est créé à partir de ce modèle et en reprend les caractéristiques et les comportements 4. Par exemple, la classe Compte décrit ce qu'est un compte, tandis que Compte(100) crée un compte précis avec son solde.
À quoi sert la programmation orientée objet ?
Elle permet de représenter des concepts du problème sous forme d'objets qui ont une structure interne et un comportement, et qui interagissent entre eux 3. Le programme devient ainsi plus proche de la situation modélisée. Elle est utilisée dans plusieurs langages, dont Python 3, avec lequel tu travailles en NSI.
Pourquoi `self` apparaît-il partout ?
Dans une méthode, self désigne l'objet sur lequel on appelle la méthode. Quand tu écris c.deposer(50), Python place c dans self automatiquement. C'est pourquoi self est le premier paramètre de chaque méthode mais qu'on ne le fournit pas à l'appel. Écrire self.solde signifie « l'attribut solde de cet objet-ci ».
Sources
- Langages et programmation - Structures de données et POO, Éduscol. Consulté le 7 novembre 2026.
- Formation NSI Terminale - Concepts POO, Université Grenoble Alpes. Consulté le 7 novembre 2026.
- Programmation orientée objet, Wikipédia. Consulté le 7 novembre 2026.
- Objet (informatique), Wikipédia. Consulté le 7 novembre 2026.
Les numéros dans le texte renvoient à ces sources. Une source qui ne dit pas ce qu'on lui fait dire ? Signale-le.