Apprenez en lisant dans l'ordre

Classes et instances — Définir ton propre type

Apprends les classes et instances Python depuis zéro. Découvre class, le rôle de self et __init__ pour fixer les attributs, le tout avec des schémas.

Comme on l'a évoqué dans le récapitulatif précédent, les types intégrés comme int, str, list et dict ne peuvent pas représenter directement des concepts métier comme « utilisateur », « produit » ou « commande ». L'étape suivante, c'est de définir ton propre type avec class — c'est la porte d'entrée vers la programmation orientée objet (POO).

Pourquoi la programmation orientée objet ?

Tout ce que tu as écrit jusqu'ici est procédural — on combine des fonctions pour piloter le comportement. Plus les programmes grandissent, plus les données liées et la logique qui les manipule ont tendance à se disperser, et les modifications comme la réutilisation deviennent plus difficiles.

Avec la programmation orientée objet (POO), tu regroupes les données associées (attributs) et les opérations qui s'y appliquent (méthodes) dans une seule unité — un objet. Cela te permet de modeler ton code autour de concepts du monde réel.

Procédural vs POO — Comment données et fonctions se relient
ProcéduralDonnées(variables)Fonctions(ailleurs)POOObjetdonnées + méthodesRegroupésensembleséparésrésultat
En code procédural, les données et les fonctions vivent à des endroits totalement séparés, et tu passes les données aux fonctions à chaque fois sous la forme function(data). La POO place les deux à l'intérieur d'un objet pour qu'ils cohabitent.

Une classe est un plan, une instance est la chose réelle

Deux termes ancrent tout en POO :

- Classe — un plan qui liste les attributs et méthodes que tu auras

- Instance — la chose réelle construite à partir de ce plan

Par exemple, définis une classe Product pour capturer le concept de produit, et tu peux créer autant d'instances individuelles de produit — apple, banana, orange — que tu en as besoin. Ensemble, classes et instances sont appelées objets.

Construire plusieurs instances depuis une seule classe
Product(classe)applename='apple'banananame='banana'orangename='orange'créercréercréer
Une classe est comme un pochoir — tu ne l'utilises pas directement. Les instances qui en naissent contiennent réellement des données et reçoivent des appels de méthode.

Définir une classe minimale

Définissons réellement une classe Product pour les articles d'un magasin. La syntaxe est class NomDeClasse:. Par convention, les noms de classe Python utilisent le CapitalizedCamelCase (Product, UserAccount, etc.).

Une variable écrite directement à l'intérieur de la classe — comme name = "apple" — est traitée comme une valeur par défaut détenue par la classe, et tu peux la lire via le nom de la classe sous la forme Product.name.

class Product:
    name = "apple"
    price = 150

# Accéder directement à la classe
print(Product.name)    # apple
print(Product.price)   # 150
Variables qui collent à la classe — Variables de classe
Product(corps de classe)name='apple'price=150détientdétient
Les variables que tu écris directement sous classname / pricecollent à la classe elle-même et peuvent être lues directement via le nom de la classe sous la forme Product.name.

Les variables écrites directement sous class sont appelées variables de classe. Elles se comportent différemment des variables d'instance (que chaque instance possède séparément), mais on reviendra sur cette distinction dans un article ultérieur. Pour l'instant, il te suffit de retenir l'idée minimale : « colle une valeur à la classe elle-même, puis lis-la avec Product.name ».

Construis une petite classe pour un inventaire.

① Définis class Product:.

② À l'intérieur, ajoute trois valeurs : name = "apple", price = 150 et stock = 10.

③ Exécute print(Product.name) / print(Product.price) / print(Product.stock) et confirme que tu peux lire chaque valeur directement depuis le nom de la classe.

(Si tu l'exécutes correctement, une explication apparaîtra.)

Éditeur Python

Exécuter le code pour voir le résultat

Utiliser __init__ pour donner à chaque instance ses propres valeurs

La classe minimale ci-dessus se contentait de coller une valeur fixe comme name = "apple" à la classe, donc chaque instance que tu construirais serait une « apple ». Dans du vrai code, tu veux plusieurs instances depuis une seule classe — apple, banana, orange — chacune avec ses propres valeurs.

L'outil pour cela est la méthode spéciale Python __init__ — aussi appelée constructeur ou initialiseur. Quand tu appelles Product("apple", 150) avec des arguments, Python appelle automatiquement __init__, et à l'intérieur tu écris self.name = name pour stocker des valeurs sur l'instance elle-même.

Doubles soulignements — Une convention Python

Les noms entourés de doubles soulignements comme __init__ sont appelés méthodes dunder. Python leur donne un sens spécial et les appelle automatiquement à certains moments__init__ quand une instance est créée, __str__ quand quelque chose est affiché, etc. On couvrira __init__ plus en profondeur et on rencontrera __del__ dans le prochain article.

Ce qui se passe quand tu appelles Product("apple", 150)
apple = Product( 'apple', 150)__init__(self, name, price)self.name = nameself.price = priceapplename='apple', price=150appel autoaffecterprêt
Appeler Product("apple", 150) fait que Python ① prépare une instance vide, ② la passe à __init__ comme self, et ③ écrit les arguments dans les attributs de cette instance — te laissant avec un objet terminé.
class Product:
    def __init__(self, name, price):    # Appelée automatiquement à la création d'une instance
        self.name = name
        self.price = price

apple = Product("apple", 150)
banana = Product("banana", 80)

print(apple.name, apple.price)     # apple 150
print(banana.name, banana.price)   # banana 80

# apple et banana sont des objets différents
print(apple is banana)             # False
Plusieurs instances depuis une seule classe
Product(classe)applename='apple', price=150banananame='banana', price=80orangename='orange', price=120
Chaque appel à Product(...) crée un objet distinct. apple, banana et orange viennent tous du même plan mais sont des objets différents, chacun avec son propre name / price.

Écris une classe Product avec __init__ et crée plusieurs instances.

① Définis class Product:. À l'intérieur de def __init__(self, name, price):, écris self.name = name et self.price = price.

② Crée deux instances : apple = Product("apple", 150) et banana = Product("banana", 80).

③ Exécute print(apple.name, apple.price) et print(banana.name, banana.price) et confirme que chacune porte ses propres valeurs.

(Si tu l'exécutes correctement, une explication apparaîtra.)

Éditeur Python

Exécuter le code pour voir le résultat

Comment fonctionnent les méthodes et self

Les attributs seuls ne font que « contenir des données » — pas très différent d'un simple dict. Le vrai intérêt de la POO, c'est que tu peux aussi écrire des opérations sur l'instance à côté des données. Ces opérations sont appelées méthodes.

Les règles des méthodes et de self
class Product:def show(self): ...1er paramètreself (requis)l'instance appelanteest passéeautomatiquementself.name→ accès attributdansdéclarevaleurvia
Une fonction écrite à l'intérieur d'une classe avec def est une méthode. Le premier paramètre self est obligatoire, et à chaque appel Python le remplit avec l'instance sur laquelle tu as appelé la méthode. À l'intérieur de la méthode, écris self.name pour accéder aux attributs de cette instance.

Quand tu écris apple.show(), Python exécute en interne Product.show(apple)self finit par contenir apple.

self pointe toujours vers l'appelant
Module
  • apple et banana sont des instances séparées
  • Quand tu appelles apple.show()
Cadre show(self)
  • self est rempli avec apple automatiquement
  • self.name lit apple.name
  • Pour banana.show(), self devient banana à la place
self n'est pas une valeur fixe — c'est l'instance sur laquelle tu as appelé la méthode. Avec la même méthode show, l'appel depuis apple lit le name d'apple, l'appel depuis banana lit celui de banana.
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def show(self):                         # Le premier paramètre est toujours self
        print(f"{self.name}: ${self.price}")

apple = Product("apple", 150)
banana = Product("banana", 80)

apple.show()    # apple: $150  équivalent à Product.show(apple) en interne
banana.show()   # banana: $80   équivalent à Product.show(banana) en interne
self est décidé au moment de l'appel de la méthode
apple.show()self = appleapple: $150banana.show()self = bananabanana: $80passesortiepassesortie
Appeler apple.show() met apple dans self, tandis qu'appeler banana.show() met banana dans self. La même méthode show s'exécute avec un self différent à chaque fois, selon l'appelant.

Ajoute une méthode à Product et appelle-la via une instance.

① Définis class Product: avec __init__(self, name, price) qui affecte self.name / self.price.

② À l'intérieur de la classe, définis def show(self): qui affiche f"{self.name}: ${self.price}".

③ Construis apple = Product("apple", 150) et banana = Product("banana", 80), puis appelle apple.show() et banana.show() pour confirmer que la même méthode s'exécute avec les valeurs de chaque instance.

Éditeur Python

Exécuter le code pour voir le résultat

self n'est qu'une convention

Syntaxiquement, le premier paramètre peut s'appeler n'importe comment — def show(this): fonctionne aussi. Mais presque toutes les bases de code Python utilisent self, alors tiens-t'en à ça. Tout autre choix déstabilise les lecteurs.

Dans cet article tu as vu les bases de la programmation orientée objet. On couvrira variables et méthodes plus en profondeur dans les articles suivants.

QUIZ

Vérification des connaissances

Répondez à chaque question une par une.

Question 1Lequel des suivants est la bonne façon de définir une classe Python ?

Question 2Qu'est-ce qui est passé automatiquement au premier paramètre self d'une méthode lors de l'appel ?

Question 3Que produit le code suivant ?
class P:
def __init__(self, x):
self.x = x
a = P(10)
b = P(20)
print(a.x + b.x)