@classmethod

Une méthode qui reçoit la classe (cls) au lieu d’un objet. Elle sert le plus souvent de constructeur alternatif.

Sur cette page

Exemple

#
Python
class Student:
    def __init__(self, name, points):
        self.name = name
        self.points = points

    @classmethod
    def from_text(cls, text):
        name, points = text.split(";")
        return cls(name, int(points))

    @classmethod
    def from_dict(cls, data):
        return cls(data["name"], data.get("points", 0))

léa = Student.from_text("Léa;250")
lucas = Student.from_dict({"name": "Lucas"})

print(léa.name, léa.points)
print(lucas.name, lucas.points)
Résultatrésultat enregistré, vous pouvez le vérifier
Léa 250
Lucas 0

Définition et utilisation

#

Le décorateur @classmethod crée une méthode de classe. Comme premier argument, elle reçoit non pas un objet, mais la classe elle-même, nommée par convention cls. On l’appelle généralement par le nom de la classe, par ex. Student.from_text("Léa;250").

Son usage le plus courant est celui de constructeur alternatif : une méthode qui crée un objet à partir de données dans un autre format, comme une chaîne, un dictionnaire ou une ligne de fichier. La méthode prépare les arguments et finit par appeler cls(...). C’est ainsi que fonctionnent les méthodes intégrées dict.fromkeys() ou datetime.fromisoformat().

Comme cls désigne la classe sur laquelle la méthode a été appelée, dans une classe dérivée, cls(...) crée un objet de la classe dérivée, et non de la classe de base. C’est un avantage par rapport à une méthode statique avec le nom de la classe écrit en dur. Les méthodes de classe ont aussi un accès pratique aux attributs de la classe, par exemple des compteurs ou des réglages partagés.

Syntaxe

#
Syntaxe
class Nom:
    @classmethod
    def méthode(cls, arguments):
        return cls(...)

Nom.méthode(arguments)

Plus d’exemples

#
cls dans une classe dérivée
Python
class Task:
    def __init__(self, number):
        self.number = number

    @classmethod
    def from_code(cls, code):
        return cls(code.removeprefix("tâche_"))

class Quiz(Task):
    pass

task = Quiz.from_code("tâche_7_3")
print(type(task).__name__, task.number)
Résultatrésultat enregistré, vous pouvez le vérifier
Quiz 7_3
Accès aux attributs de classe
Python
class Player:
    online = 0

    def __init__(self, nick):
        self.nick = nick
        Player.online += 1

    @classmethod
    def status(cls):
        return f"Joueurs en ligne : {cls.online}"

Player("léa_dev")
Player("lucas99")
print(Player.status())
Résultatrésultat enregistré, vous pouvez le vérifier
Joueurs en ligne : 2

Bonnes pratiques

#
  • Donnez aux constructeurs alternatifs des noms commençant par from_, par ex. from_json() ou from_row(). C’est une convention connue de la bibliothèque standard.
  • Dans une méthode de classe, créez les objets via cls(...), et non via le nom de la classe. Elle fonctionne alors correctement aussi dans les classes dérivées.
  • Si une méthode n’a besoin ni de l’objet ni de la classe, @staticmethod suffit.

Entrées associées

#

Vous voyez une erreur ou il manque un exemple ? Écrivez-nous.