Python >> Tutoriel Python >  >> Python

Méthode de classe Python()

La fonction intégrée de Python classmethod () préfixe une définition de méthode dans une classe comme une annotation @classmethod . Cette annotation transforme une méthode d'instance normale en une méthode de classe. La différence entre la classe et la méthode d'instance est que Python passe la classe elle-même comme premier argument implicite de la méthode plutôt que l'instance sur laquelle elle est appelée.

Dans ce tutoriel, je vais vous montrer l'un des secrets peu connus de Python qui sépare les intermédiaires des experts :les méthodes de classe. Vous connaissez peut-être la différence entre une méthode d'instance et une méthode de classe sur le plan conceptuel. (Si vous ne le faites pas, ce tutoriel est pour vous.) Mais savez-vous aussi comment créer une méthode de classe en Python ? Sinon, continuez à lire, car ce tutoriel vous le montrera !

Méthode de classe de syntaxe

Syntax: 
classmethod(function)    # <- – This is considered unpythonic
@classmethod                        # <- – As a prefix before the used method

La façon la plus Pythonique de déclarer une méthode de classe est la syntaxe de décorateur suivante :

class C:
    @classmethod
    def f(cls, arg1, arg2, ...):
        None

Comment appeler une méthode de classe ?

Il existe deux manières d'utiliser une méthode de classe :

  • Vous pouvez l'appeler sur une classe telle que C.f(arg1, arg2, ...) , ou
  • Vous pouvez l'appeler sur une instance telle que C().f(arg1, arg2, ...) .

Notez que Python passe implicitement la classe elle-même - en Python, tout ce qui inclut une classe est un objet - comme premier argument. En gros, si vous appelez C.f(arg1, arg2, ...) , Python exécute vraiment f(C, arg1, arg2, ...) avec l'objet de classe passé en premier argument.

Exemple de méthode de classe

Quand utiliser une méthode de classe ? Vous constaterez que les méthodes de classe sont souvent utilisées dans un modèle de fabrique. Un modèle d'usine est l'un des modèles de développement logiciel les plus populaires :une méthode dite d'usine crée de nouvelles instances d'un certain type. Il est responsable de la création des instances à partir d'une définition de classe donnée.

Dans l'exemple suivant, vous définissez une classe Coffee qui représente un vrai café servi dans un café-bar. Il existe de nombreuses spécialités telles que le Cappuccino (80% lait, 20% café), l'Espresso Macchiato (30% lait, 70% café) et le Latte Macchiato (95% lait, 5% café).

Vous utilisez les méthodes de classe pour permettre aux utilisateurs d'appeler facilement les méthodes d'usine au lieu de définir eux-mêmes le niveau de lait. Au lieu d'appeler le Coffee(80, 20, 'Arrabica') , un utilisateur peut simplement appeler cappuccino() pour créer la même instance de la classe Coffee . Cela simplifie la création de nouvelles instances et peut améliorer la lisibilité et la convivialité de votre code :

class Coffee:

  def __init__(self, milk, beans):
    self.milk = milk # percentage
    self.coffee = 100-milk # percentage
    self.beans = beans


  def __repr__(self):
    return f'Milk={self.milk}% Coffee={self.coffee}% Beans={self.beans}'


  @classmethod
  def cappuccino(cls):
    return clf(80, 'Arrabica')
  

  @classmethod
  def espresso_macchiato(cls):
    return cls(30, 'Robusta')
  

  @classmethod
  def latte(cls):
    return cls(95, 'Arrabica')


print(Coffee.cappuccino())
print(Coffee.espresso_macchiato())
print(Coffee.latte())

Les trois lignes de sortie sont :

Milk=80% Coffee=20% Beans=Arrabica
Milk=30% Coffee=70% Beans=Robusta
Milk=95% Coffee=5% Beans=Arrabica

Vous pouvez exécuter cet exemple dans notre bloc-notes Jupyter interactif :

Méthode de classe d'exemple interactif

Exercice :Pouvez-vous créer une autre spécialité de café ?

Convention de dénomination des méthodes de classe : cls contre self

Dans l'exemple précédent, vous avez vu la convention de nommage du premier argument d'une méthode de classe :ce sont les trois caractères cls -abréviation de "classe", mais nous ne pouvons pas prendre cela car class est un mot clé réservé. Vous pouvez utiliser le nom de votre choix, mais en utilisant le nom cls est la convention attendue et fortement recommandée. La convention de nommage du premier argument implicite des méthodes d'instance est le nom self .

Article connexe : Soi en Python

La méthode de classe est un décorateur de fonction

Les décorateurs aident à ajouter des fonctionnalités au code existant sans avoir à modifier le code lui-même. Les décorateurs sont appelés ainsi parce qu'ils décorent le code, ils ne modifient pas le code, mais ils font en sorte que le code fasse différentes choses en utilisant la décoration. Maintenant que nous avons compris les fermetures, nous pouvons progresser étape par étape pour comprendre et utiliser les décorateurs.

Le @classmethod est un décorateur de fonction. C'est l'abréviation d'appeler classmethod(m) pour la méthode m que tu décorerais.

Voici le même exemple de café simplifié sans utiliser de décorateur et en utilisant classmethod() à la place :

class Coffee:

  def __init__(self, milk, beans):
    self.milk = milk # percentage
    self.coffee = 100-milk # percentage
    self.beans = beans
    


  def __repr__(self):
    return f'Milk={self.milk}% Coffee={self.coffee}% Beans={self.beans}'


  def cappuccino(cls):
    return cls(80, 'Arrabica')
  

Coffee.cappuccino = classmethod(Coffee.cappuccino)
print(Coffee.cappuccino())

Le résultat est le même :

Milk=80% Coffee=20% Beans=Arrabica

Cependant, ce n'est pas la méthode recommandée :utilisez plutôt un décorateur avec l'annotation @ !

Article connexe : Décorateurs

Méthode de classe vs méthode d'instance

Si vous n'utilisez pas le @classmethod annotateur, vous obtenez une méthode d'instance par défaut. La méthode d'instance nécessite que le premier argument self est une référence à l'instance elle-même sur laquelle la méthode est appelée. La méthode de classe attend une référence à la classe, pas à l'instance, comme premier argument cls . Ainsi, la différence entre les méthodes de classe et d'instance est que Python passe la classe plutôt que l'instance (objet) comme premier argument implicite.

Voici un exemple minimal d'une classe et d'une méthode d'instance :

class C:

    @classmethod
    def f(cls):
        None


    # instance method
    def g(self):
        None



# call class method:
C.f()

# call instance method:
C().g()

Il existe deux manières d'utiliser une méthode de classe :

  • Vous pouvez l'appeler sur une classe telle que C.f(arg1, arg2, ...) , ou
  • Vous pouvez l'appeler sur une instance telle que C().f(arg1, arg2, ...) .

Mais il n'y a qu'une seule façon d'utiliser une méthode d'instance :

  • Vous pouvez l'appeler sur une instance telle que C().g() .

Méthode de classe vs méthode statique

Vous connaissez peut-être les méthodes statiques des langages de programmation tels que C++ ou Java. Ce sont des méthodes qui existent indépendamment du fait que vous ayez ou non créé une instance de la classe. C'est pourquoi ils n'utilisent aucune variable d'instance dans le corps de la méthode. Si vous souhaitez utiliser une méthode statique en Python, vous devez utiliser le @staticmethod annotation plutôt que le @classmethod annotation. La différence est que les méthodes statiques n'attendent pas une référence à l'instance ou à la classe comme premier argument implicite.

Voici un exemple comparant les méthodes de classe, les méthodes d'instance et les méthodes statiques :

class C:

    @classmethod
    def f(cls):
        None


    # instance method
    def g(self):
        None


    @staticmethod
    def h():
        None


# call class method:
C.f()

# call instance method:
C().g()


# call static method:
C.h()

Résumé

La fonction intégrée de Python classmethod () préfixe une définition de méthode dans une classe comme une annotation @classmethod .

class C:


    @classmethod
    def f(cls, arg1, arg2, ...):
        None

Cette annotation transforme une méthode d'instance normale en une méthode de classe.

La différence entre la classe et la méthode d'instance est que Python passe la classe elle-même comme premier argument implicite de la méthode plutôt que l'instance sur laquelle elle est appelée :

class C:


    @classmethod
    def f(cls, arg1, arg2, ...):
        None


    # instance method
    def g(self, arg1, arg2, ...):
        None

Voulez-vous améliorer vos compétences Python d'une manière amusante et facile à consommer ? Considérez les ressources suivantes et devenez un maître codeur !


Post précédent