En Python, changez le comportement de la méthode en fonction de la façon dont elle est appelée

Définition normale et résultat de l'appel

Il existe trois types de méthodes dans les classes Python.

class C:
  val = 20
  def __init__(self):
    self.val = 1
  def normal_method(self, v):
    return self.val + v + 2
  @classmethod
  def class_method(cls, v):
    return cls.val + v + 3
  @staticmethod
  def static_method(v):
    return C.val + v + 4

i = C()
i.normal_method(5)    # i.val + 5 + 2 = 1 + 5 + 2 = 8
i.class_method(6)     # C.val + 6 + 3 = 20 + 6 + 3 = 29
i.static_method(7)    # C.val + 7 + 4 = 20 + 7 + 4 = 31
C.normal_method(5)    # requires 2 args but 1: error
C.normal_method(i, 6) # i.val + 6 + 2 = 1 + 6 + 2 = 9
C.normal_method(C, 7) # C.val + 7 + 2 = 20 + 7 + 2 = 29
C.class_method(8)     # C.val + 8 + 3 = 20 + 8 + 3 = 31
C.static_method(9)    # C.val + 9 + 4 = 20 + 9 + 4 = 33

Changer le comportement en fonction de la façon dont la méthode est appelée

Les méthodes normales sont toujours des fonctions.

En prenant cela comme un contre-produit, le comportement peut être modifié par le premier argument.

class C:
  #Ajouté à ce qui précède
  def trick_method(arg, v):
    if isinstance(arg, C):
      return arg.val * 2 * v
    else:
      return C.val + arg * v

i.trick_method(4)    # i.val * 2 * 4 = 1 * 2 * 4 = 8
C.trick_method(5)    # requires 2 args but 1: error
C.trick_method(6, 7) # C.val + 6 * 7 = 20 + 6 * 7 = 62
C.trick_method(i, 8) # i.val * 2 * 8 = 1 * 2 * 8 = 16
C.trick_method(C, 9) # C.val + C * v: error

Le trick_method () ci-dessus se comporte comme une méthode normale via une instance et comme une méthode statique via une classe.

Normalement, si le comportement est différent, il devrait s'agir d'une méthode différente.

Illustration

J'ai trouvé une utilisation si étrange lors de la création d'une classe qui gère les instances en tant que groupe.

class Student:
  rooms = {}
  def __init__(self, room):
    self.myroom = room
    if not room in Student.rooms:
      Student.rooms [room] = []
    Student.rooms [room].append(self)

  def classmates(self_or_room):
    if isinstance(self_or_room, Student):
      self = self_or_room
      for s in Student.rooms[self.myroom]:
        if s != self:
          yield s
    elif self_or_room in Student.rooms:
      room = self_or_room
      return iter(Student.rooms[room])

Ann = Student('3-A')
Bob = Student('3-B')
Cathy = Student('3-B')
Dan = Student('3-A')
Ellen = Student('3-A')
Fred = Student('3-B')

mates_of_ann = Ann.classmates() # Dan, Ellen
mates_of_3A = Student.classmates('3-A') # Ann, Dan, Ellen

mates_of_bob = Bob.classmates() # Cathy, Fred
mates_of_3B = Student.classmates('3-B') # Bob, Cathy, Fred

Mise en garde

Cette méthode ne peut pas être utilisée avec des méthodes avec des décorateurs (comme «@ property» ou «@ classmethod»).

Recommended Posts

En Python, changez le comportement de la méthode en fonction de la façon dont elle est appelée
Découvrez le nom de la méthode qui l'a appelée à partir de la méthode qui est python
Différence de sys.path en fonction du démarrage de Python (v3.8.2)
Comment est le progrès? Continuons le boom ?? en Python
Vérifiez le comportement du destroyer en Python
La valeur de retour de len ou unichr peut changer selon qu'il s'agit de UCS-2 ou UCS-4.
Comment la référence du tableau python change en fonction de la présence ou de l'absence d'indices
Comment obtenir le nombre de chiffres en Python
Différence de résultats en fonction de l'argument du multiprocessus.
rsync Le comportement change en fonction de la présence ou de l'absence de la barre oblique de la source de copie
Comment vérifier en Python si l'un des éléments d'une liste est dans une autre liste
Quelle est la force de votre Qiita? Statistiques sur le nombre de Contributes visibles dans les données
Remarque sur le comportement par défaut de collate_fn dans PyTorch
Test.py n'est pas reflété sur le serveur Web dans Python3.
La plage d'adresses IP AWS est différente selon la méthode d'acquisition.
Sakura L'histoire du fonctionnement de la bouteille Python sur Internet
Comment utiliser la méthode __call__ dans la classe Python
Comment déterminer l'existence d'un élément sélénium en Python
Comment modifier le niveau de journalisation d'Azure SDK pour Python
Malheureusement, il n'y a pas de sens d'unité dans la méthode where
Comment connaître la structure interne d'un objet en Python
Comment changer la couleur du seul bouton pressé avec Tkinter
Est-il facile de synthétiser un médicament sur le marché?
Comment vérifier la taille de la mémoire d'une variable en Python
Supprimer un caractère spécifique en Python s'il s'agit du dernier
Comment déterminer qu'une clé croisée a été entrée dans Python3
N'hésitez pas à changer l'étiquette de légende avec Seaborn en python
Comment utiliser l'astérisque (*) en Python. C'est peut-être tout? ..
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
Une fonction qui mesure le temps de traitement d'une méthode en python
Comment mettre à jour la version Python de Cloud Shell dans GCP
J'ai fait beaucoup de recherches sur la façon dont Python est exécuté
Obtenez le nombre de lecteurs d'articles sur Mendeley en Python
Une raison simple pour laquelle la valeur de retour de round (2.675,2) est de 2,67 en python (elle devrait être de 2,68 en réalité ...)
Changer la longueur des chaînes csv Python
Changement de comportement de [Diagramme / Chronologie] dans Chorégraphe 2.5.5.5
Changer la saturation et la clarté des spécifications de couleur comme # ff000 dans python 2.5
Modifions automatiquement la palette de couleurs d'iTerm2 en fonction de l'heure de la journée
Le résultat de l'installation de python sur Anaconda
[Java] [Linux] Etude de la manière dont l'implémentation des processus enfants Java sous Linux est réalisée
Qu'est-ce que "mahjong" dans la bibliothèque Python? ??
[python] [meta] Le type de python est-il un type?
Principes de base pour exécuter NoxPlayer en Python
Quel genre de livre est le "Python Crash Course" le plus vendu au monde?
Changer l'ordre de PostgreSQL dans Heroku
À la recherche du FizzBuzz le plus rapide en Python
[Introduction à Python] Quelle est la méthode de répétition avec l'instruction continue?
Comment utiliser is et == en Python
Comment saisir une chaîne de caractères en Python et la sortir telle quelle ou dans la direction opposée.
Une histoire sur un ingénieur qui a remarqué l'émo de la cryptographie et tente de l'implémenter en Python
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
[Linux] Différence d'informations temporelles en fonction de l'ID d'horloge de la fonction clock_gettime ()
Je souhaite utiliser Python dans l'environnement de pyenv + pipenv sous Windows 10
Si branche en fonction de l'existence ou non d'un élément spécifique dans la liste
J'étais en difficulté car le comportement du conteneur docker n'a pas changé
Affiche automatiquement les paroles de la chanson en cours de lecture sur iTunes en Python
[Python] Comment nommer les données de table et les sortir avec csv (méthode to_csv)
Définir la limite supérieure du nombre de répétitions de fonctions récursives en Python
Différences de comportement de chaque langage LL lorsque l'index de la liste est ignoré