Apprenez en lisant dans l'ordre

Méthodes d'instance, de classe et statiques — Les trois types de méthodes

Apprends les trois types de méthodes Python — d'instance, de classe et statique — avec des schémas. Découvre l'utilisation de self / cls / sans premier argument et quand choisir chacune.

La dernière fois on a couvert la différence entre variables de classe et d'instance. Toutes les méthodes qu'on a écrites jusqu'ici sous la forme def method(self, ...) sont des méthodes d'instance, mais les classes Python ont deux autres types — les méthodes de classe et les méthodes statiques. Cette fois on va trier les trois types et comment choisir entre elles.

Il existe trois types de méthodes

Les méthodes d'une classe Python tombent dans trois types, distingués par ce qu'elles prennent comme premier argument :

- Méthode d'instance — premier paramètre self. Reçoit l'instance elle-même.

- Méthode de classe — premier paramètre cls. Reçoit la classe elle-même. Décorée avec @classmethod.

- Méthode statique — pas de premier paramètre. Ne prend ni self ni cls. Décorée avec @staticmethod.

Le type détermine ce que chaque méthode peut atteindre. Seules les méthodes d'instance peuvent toucher aux variables d'instance self.x. Les méthodes de classe sont la façon de travailler avec les variables de classe depuis le côté classe, et les méthodes statiques sont pour la logique pure qui ne touche ni l'un ni l'autre.

Ce que les trois types de méthodes peuvent atteindre
Méthoded'instance (self)vars d'instance+ vars de classe+ argsMéthodede classe (cls)vars de classe+ argsMéthodestatique (aucun)args uniquementatteintatteintatteint
Les méthodes d'instance atteignent variables d'instance + variables de classe + arguments — tout. Les méthodes de classe atteignent variables de classe + arguments. Les méthodes statiques atteignent les arguments uniquement.

Méthodes d'instance — Prendre self

La forme def method(self, ...) que tu as écrite tout du long est une méthode d'instance. Le premier paramètre self est rempli automatiquement avec l'instance sur laquelle la méthode a été appelée, donc tu peux atteindre les variables d'instance comme self.name.

Quand tu écris apple.show(), Python le traduit en interne en Product.show(apple). Tu peux voir les méthodes comme « des fonctions qui prennent une instance comme premier argument ».

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def total_with_tax(self, tax_rate):    # méthode d'instance
        return int(self.price * (1 + tax_rate))

apple = Product("apple", 150)
print(apple.total_with_tax(0.1))  # 165

# Équivalent en interne à ceci
print(Product.total_with_tax(apple, 0.1))  # 165
Comment self te permet d'atteindre les variables d'instance
__init__self.price = 150appleprice = 150apple.total_with_tax(0.1)self reçoitappleself.price→ 150①aff②appel③lect
__init__ affecte apple.price = 150 → ② appeler apple.method(0.1) met apple dans self → ③ self.price lit la valeur affectée sur l'instance.

Méthodes de classe — @classmethod et cls

Une méthode de classe est définie avec le décorateur @classmethod, avec cls comme premier paramètre (un nom conventionnel). cls contient automatiquement la classe elle-même — dans ce cas le plan Product.

Utilise les méthodes de classe quand tu veux lire ou écrire une variable de classe ou construire et renvoyer une instance unique (une factory). Tu peux aussi les appeler via une instance (apple.method()), mais les appeler sur la classe avec Product.method() est le standard.

class Product:
    total_count = 0           # variable de classe

    def __init__(self, name, price):
        self.name = name
        self.price = price
        Product.total_count += 1

    @classmethod              # ① renvoie une variable de classe
    def get_total(cls):
        return f"{cls.total_count} produits enregistrés"

    @classmethod              # ② construit et renvoie une instance (factory)
    def from_csv_row(cls, row):
        name, price = row.split(",")
        return cls(name, int(price))

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

print(Product.get_total())             # 2 produits enregistrés
orange = Product.from_csv_row("orange,120")
print(orange.name, orange.price)        # orange 120
Comment fonctionne une méthode de classe
@classmethoddécorateurdef get_total( cls):Product.get_total()cls = Product(la classe)cls.total_count(var de classe)déclareautovia lookup
Appeler get_total(cls) (décorée avec @classmethod) sous la forme Product.get_total() met automatiquement la classe Product elle-même dans cls. À partir de là, tu peux atteindre les variables de classe comme cls.total_count.
self vs cls
Méthode d'instance
  • def total_with_tax(self, tax_rate):
  • Appel : apple.total_with_tax(0.1)
  • self devient apple
  • Atteint la variable d'instance self.price
Méthode de classe
  • Décorée avec @classmethod
  • def get_total(cls):
  • Appel : Product.get_total() (depuis la classe)
  • cls devient Product
  • Atteint la variable de classe cls.total_count
self est « l'instance depuis laquelle tu as appelé » ; cls est « la classe elle-même ». Quand le travail porte uniquement sur les variables de classe, passer par cls rend l'intention plus claire.

Écris une méthode de classe get_total qui renvoie « le nombre de produits créés jusqu'ici ».

① Dans class Product:, ajoute une variable de classe total_count = 0.

② Dans __init__(self, name, price), après self.name = name / self.price = price, écris Product.total_count += 1.

③ Définis get_total décorée avec @classmethod et premier paramètre cls, qui renvoie cls.total_count.

④ Construis Product("apple", 150) et Product("banana", 80), puis print(Product.get_total()) et confirme que ça affiche 2.

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

Éditeur Python

Exécuter le code pour voir le résultat

Méthodes statiques — @staticmethod

Une méthode statique est définie avec @staticmethod et ne prend ni self ni cls. C'est « une fonction normale qui vit dans la classe » — elle accomplit son travail en utilisant uniquement ses arguments, sans accès aux variables d'instance ou de classe.

Elle convient aux cas où le travail est lié à la classe mais ne dépend pas d'une instance particulière ou de l'état de la classe — validation d'entrée, formatage, calculs purs utilisant des constantes. Utilise-la pour garder les fonctions utilitaires à côté de la classe associée plutôt que de les écrire comme des fonctions autonomes.

class Product:
    def __init__(self, name, price):
        if not Product.is_valid_price(price):
            raise ValueError(f"prix invalide : {price}")
        self.name = name
        self.price = price

    @staticmethod
    def is_valid_price(price):           # pas de self, pas de cls
        return 0 <= price <= 1_000_000

print(Product.is_valid_price(150))      # True
print(Product.is_valid_price(-1))       # False

# Product("apple", -1)  # ValueError: prix invalide : -1

Les méthodes statiques fonctionnent depuis la classe ou l'instance

Les deux Product.is_valid_price(150) et apple.is_valid_price(150) fonctionnent de la même façon. Mais comme la méthode n'utilise pas réellement l'instance, l'appeler sur la classe rend l'intention plus claire. Écrire apple.is_valid_price(...) fait douter le lecteur — « est-ce que ça dépend de l'état d'apple ? » — à éviter.

Écris une méthode statique pour la validation de prix.

① Dans class Product:, définis is_valid_price(price) comme une @staticmethod qui renvoie 0 <= price <= 1_000_000.

② Au début de __init__(self, name, price), écris if not Product.is_valid_price(price): raise ValueError("prix invalide") avant d'affecter self.name / self.price.

③ Confirme que Product("apple", 150) réussit et que Product("sea_urchin", -1) échoue avec ValueError en l'entourant de try / except.

Éditeur Python

Exécuter le code pour voir le résultat

Choisir entre les trois

Laquelle utiliser peut être décidé mécaniquement en fonction de « ce que la méthode a besoin de toucher ».

- Touche les variables d'instance (self.x)méthode d'instance

- Touche seulement les variables de classe (cls.x)méthode de classe

- Ne touche ni l'un ni l'autre (juste piloté par les arguments)méthode statique

En cas de doute : vérifie d'abord si tu touches aux variables d'instance. Sinon, vérifie les variables de classe. Si ni l'un ni l'autre, statique. Cet ordre ne te trompera pas.

Schéma de décision pour les types de méthodes
toucheself.x ?Méthoded'instancetouchecls.x ?Méthodede classene toucheni l'un ni l'autreMéthodestatiquelogique purevivant dans la classeOuiNonOuiNonuse
Première branche : touches-tu à la variable d'instance self.x ? Suivante : gères-tu des variables de classe ? Si ni l'un ni l'autre, statique est le bon choix.
TypeDécorateur1er paramètreUsage typique
Méthode d'instanceaucunselfMéthodes normales qui lisent/écrivent self.x
Méthode de classe@classmethodclsLire/écrire des variables de classe, factories
Méthode statique@staticmethodaucunValidation, formatage, logique pure

Mets les trois types de méthodes dans une seule classe et ressens les différences.

① Définis class Product: avec la variable de classe total_count = 0 et __init__(self, name, price). Au début de __init__, lève ValueError si Product.is_valid_price(price) échoue ; sinon affecte self.name = name / self.price = price et exécute Product.total_count += 1.

② Ajoute une méthode d'instance total_with_tax(self, tax_rate) qui renvoie int(self.price * (1 + tax_rate)).

③ Ajoute une méthode de classe get_total(cls) décorée avec @classmethod qui renvoie cls.total_count.

④ Ajoute une méthode statique is_valid_price(price) décorée avec @staticmethod qui renvoie 0 <= price <= 1_000_000.

⑤ Construis apple = Product("apple", 150) et print à la fois apple.total_with_tax(0.1) et Product.get_total().

Éditeur Python

Exécuter le code pour voir le résultat

Avec cet article, tu as couvert les trois types de méthodes — instance / classe / statique — et comment choisir entre eux. Cela complète la boîte à outils essentielle des classes, instances, attributs et méthodes en Python. À partir d'ici, tu peux passer aux trois piliers de la programmation orientée objet : l'encapsulation (contrôler la visibilité des attributs), l'héritage (reprendre les capacités d'une autre classe) et le polymorphisme (le même nom de méthode se comportant différemment selon le type).

QUIZ

Vérification des connaissances

Répondez à chaque question une par une.

Question 1Quel décorateur utilises-tu pour définir une méthode statique ?

Question 2Quelle méthode est la mieux adaptée à @classmethod ?

Question 3Quelles méthodes peuvent être appelées sans créer d'instance ? (Choisis la réponse unique la plus appropriée si plusieurs s'appliquent.)