ComparaisonComparaisons

@staticmethod vs @classmethod

@staticmethod agit comme une fonction ordinaire sans argument automatique ; @classmethod reçoit la classe comme cls et sert souvent de constructeur alternatif.

Sur cette page

Comparaison point par point

#
  • Premier argument

    @staticmethod
    Aucun
    @classmethod
    cls (la classe)
  • Accès aux attributs de la classe

    @staticmethod
    Non, sauf via le nom de la classe écrit en dur
    @classmethod
    Oui, via cls
  • Création d’un objet via cls(...)

    @staticmethod
    Non
    @classmethod
    Oui, c’est un usage typique
  • Comportement dans une classe dérivée

    @staticmethod
    Non applicable, aucune référence à la classe
    @classmethod
    cls est la classe dérivée, pas la classe de base
  • Appel

    @staticmethod
    Class.method(args)
    @classmethod
    Class.method(args)
  • Usage typique

    @staticmethod
    Validation, calculs indépendants des données de l’objet
    @classmethod
    Constructeurs alternatifs (from_text, from_dict)

Exemple

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

    @staticmethod
    def is_valid(points):
        return 0 <= points <= 100

    @classmethod
    def from_percent(cls, percent, maximum):
        return cls(round(percent / 100 * maximum))

print(Grade.is_valid(120))
grade = Grade.from_percent(75, 80)
print(grade.points)
Résultatrésultat enregistré, vous pouvez le vérifier
False
60

Définition et utilisation

#

Les deux décorateurs définissent une méthode que vous appelez par le nom de la classe, sans créer d’objet. Aucune des deux ne reçoit self, donc elle n’a pas accès aux données d’un objet précis.

Elles diffèrent par leur premier argument. Une méthode statique ne reçoit rien automatiquement : c’est une fonction ordinaire, simplement placée dans la classe pour l’organisation. Une méthode de classe reçoit comme premier argument la classe elle-même (cls), ce qui lui permet de référencer ses attributs et, surtout, de créer un objet via cls(...). Dans une classe dérivée, cls désigne cette classe dérivée, et non la classe où la méthode a été écrite.

Utilisez @staticmethod pour une fonction utilitaire qui appartient logiquement à la classe, par ex. une validation ou un calcul, mais qui n’a besoin ni de l’objet ni de la classe. Utilisez @classmethod quand la méthode doit créer des objets à partir de données dans un format différent du constructeur normal, par ex. from_text() ou from_dict(), ou quand elle a besoin d’accéder aux attributs de la classe, comme un compteur partagé.

Syntaxe

#
Syntaxe
class Name:
    @staticmethod
    def method(arg):
        ...

    @classmethod
    def other(cls, arg):
        return cls(arg)

Plus d’exemples

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

    @classmethod
    def from_code(cls, code):
        return cls(code.removeprefix("tache_"))

class Quiz(Task):
    pass

task = Quiz.from_code("tache_7_3")
print(type(task).__name__, task.number)
Résultatrésultat enregistré, vous pouvez le vérifier
Quiz 7_3
Une méthode statique ne voit ni la classe ni l’objet
Python
class Course:
    count = 0

    def __init__(self, title):
        self.title = title
        Course.count += 1

    @staticmethod
    def slugify(title):
        return title.lower().replace(" ", "-")

python_course = Course("Python pour débutants")
print(Course.slugify(python_course.title))
print(Course.count)
Résultatrésultat enregistré, vous pouvez le vérifier
python-pour-débutants
1

Bonnes pratiques

#
  • Si une méthode n’utilise ni self ni cls, elle devrait probablement être statique, ou même en dehors de la classe.
  • Nommez les constructeurs alternatifs avec le préfixe from_, par ex. from_json(), 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 avec le nom de la classe écrit en dur, pour qu’elle fonctionne correctement aussi dans les classes dérivées.

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