#!⌨

Python et les méthodes

En Python, une méthode est un objet comme les autres. Une fois déclarée, on peut donc la manipuler dans d'autres structures de données, et avoir envie de l'appeler depuis ces structures.

>>> class MyClass:
...     def method(self):
...         print 'test'
...     # je veux appeler depuis une méthode chacune
...     # des méthodes listées ci-dessous :
...     methods = [method]

Comment réaliser cette tâche ? Si je boucle sur les élémentes de methods et que j'appelle chacun des éléments, j'obtiens TypeError: method() takes exactly 1 argument (0 given). Il doit bien y avoir un moyen. Reprenons depuis le cas connu.

Appeler une méthode sur une instance est plutôt simple :

>>> class MyClass:
...     def method(self):
...         print 'test'
...
>>> object = MyClass()
>>> object.method()
test

Ici, j'énonce l'évidence : object.method() appelle la méthode method de notre objet object. Jusque là, rien de compliqué. Par contre, qu'est devenu le paramètre self de la déclaration de méthode ? On appelle la méthode sans le paramètre ? Pourquoi n'as-t-on pas une TypeError: method() takes exactly 1 argument (0 given) ?

La réponse est dans la partie sur les object méthodes dans la documentation officielle de Python :

The special thing about methods is that the object is passed as the first argument of the function.

On pourrait alors appeler directement notre méthode en passant par la classe et non plus par l'objet :

>>> MyClass.method(object)
test

Une méthode n'est pas une fonction comme les autres. En fait, ce n'est pas non plus une fonction : c'est un callable. Dans la hiérarchie des types standards de Python, on trouve que les méthodes et les fonctions sont deux sous-types du callable. Naturellement, j'aurais dit qu'une méthode est un sous type d'une fonction. La différence est simplement qu'une méthode combine une instance d'objet avec une fonction définie par l'utilisateur.

Pour revenir à mon besoin (manipuler une méthode à travers une structure de données), il suffit donc d'appeler la méthode de la seconde manière présentée :

>>> class MyClass:
...     def method(self):
...         print 'test'
...     # je veux appeler depuis une méthode chacune
...     # des méthodes listées ci-dessous :
...     methods = [method]
...     def call(self):
...         for m in self.methods:
...             m(self)
...
>>> object = MyClass()
>>> object.call()
test
>>>

Enfin, voici une dernière pépite sur les méthodes. Je voulais en savoir plus sur le mot self. Je me suis donc rendu dans le paragraphe sur les mots clefs de la documentation de python, et je n'y ai pas trouvé le mot self. Et là, je me suis dit :

>>> class MyClass:
...     message = 'truc'
...     # pas de self dans la définition de la méthode
...     def call(this):
...         print this.message
...
>>> object = MyClass()
>>> object.call()
truc
>>>

On n'est donc pas obligé de nommer le premier argument d'une méthode self. Ici, j'ai utilisé le mot clef Java this (qui est vraiment un mot clef pour le coup) pour nommer mon instance d'objet. Et ça marche ! Mais ne faites pas ça dans du vrai code. C'est idiot : ça rendra votre code moins clair et ça va à l'encontre de la PEP8.