Lier des méthodes aux classes et instances Python

Étant donné que Python est un langage dynamique, vous pouvez redéfinir et ajouter dynamiquement des méthodes aux classes et instances au moment de l'exécution.

class User:
    pass

user1 = User()
user1.set_username('kaito')

L'appel d'une propriété ou d'une méthode non définie entraînera une erreur.


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-30-815371892d44> in <module>
      3 
      4 user1 = User()
----> 5 user1.set_username('kaito')

AttributeError: 'User' object has no attribute 'set_username'

Vous pouvez ajouter des méthodes ultérieurement en utilisant MethodType </ code>. Tout d'abord, définissez la méthode comme une fonction (vous devez définir self comme un argument comme une méthode).

def set_username(self, username):
    self.username = username

Ensuite, liez la méthode à l'instance.

from types import MethodType
user1.set_username = MethodType(set_username, user1)
user1.set_username('kaito')
user1.set_username

Vous pouvez voir qu'il est lié en tant que méthode.

<bound method set_username of <__main__.User object at 0x111f55438>>

Que se passe-t-il si j'attribue directement sans utiliser MethodType </ code>?

user1.set_username = set_username
user1.set_username

C'est juste une référence à un objet fonction.

<function __main__.set_username(self, username)>

Essayez de l'exécuter.

user1.set_username(user1, 'kaito') 

C'est une fonction, pas une méthode, donc ça ne s'attribue pas.

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-42-70cc4337e082> in <module>
----> 1 user1.set_username('kaito')

TypeError: set_username() missing 1 required positional argument: 'username'

Il peut être exécuté en se donnant explicitement.

user1.set_username(user1, 'kaito')

Et la classe User?

User.set_username

Je l'ai ajouté uniquement à l'instance, donc la classe ne change pas.

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-38-40cdce039232> in <module>
----> 1 User.set_username

AttributeError: type object 'User' has no attribute 'set_username'

Si vous souhaitez ajouter une méthode à une classe, vous pouvez le faire de la même manière.

User.set_username = MethodType(set_username, User)
User.set_username

L'adresse mémoire n'est pas affichée comme l'instance, mais elle est ajoutée correctement.

<bound method set_username of <class '__main__.User'>>

Recommended Posts