223 votes

Pourquoi faut-il avoir explicitement l'argument "self" dans une méthode Python ?

Lorsque l'on définit une méthode sur une classe en Python, cela ressemble à quelque chose comme ceci :

class MyClass(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

Mais dans certains autres langages, comme le C#, vous disposez d'une référence à l'objet auquel la méthode est liée avec le mot clé "this" sans le déclarer comme argument dans le prototype de la méthode.

S'agit-il d'une décision intentionnelle de conception du langage en Python ou existe-t-il des détails d'implémentation qui nécessitent le passage de "self" comme argument ?

16 votes

Je parie que vous seriez également intéressé de savoir pourquoi vous devez écrire explicitement self pour accéder aux membres - stackoverflow.com/questions/910020/

1 votes

Mais ça ressemble un peu à une plaque de cuisson.

0 votes

Un peu confus mais à comprendre stackoverflow.com/a/31367197/1815624

97voto

S.Lott Points 207588

J'aime citer le Zen de Python de Peters. "L'explicite est meilleur que l'implicite".

En Java et C++, ' this. ' peut être déduit, sauf lorsque vous avez des noms de variables qui rendent la déduction impossible. Vous en avez donc parfois besoin et parfois non.

Python choisit de rendre ce genre de choses explicites plutôt que de se baser sur une règle.

En outre, comme rien n'est implicite ou supposé, certaines parties de la mise en œuvre sont exposées. self.__class__ , self.__dict__ et d'autres structures "internes" sont disponibles de manière évidente.

58 votes

Bien que ce serait bien d'avoir un message d'erreur moins cryptique lorsque vous l'oubliez.

2 votes

Vous pouvez l'épeler comme bon vous semble (my, this, whatever) et pour certains types de méthodes de classe, il change de signification. Il n'est pas facile de déterminer votre intention et de donner un "meilleur" message.

11 votes

Cependant, lorsque vous appelez une méthode, vous n'avez pas besoin de passer une variable objet, n'est-ce pas une violation de la règle d'explicitation ? Si l'on veut rester zen, cela doit être quelque chose comme : object.method(object, param1, param2). Cela semble quelque peu incohérent...

73voto

Ryan Points 7423

C'est pour minimiser la différence entre les méthodes et les fonctions. Il permet de générer facilement des méthodes dans les métaclasses, ou d'ajouter des méthodes au moment de l'exécution à des classes préexistantes.

par exemple

>>> class C(object):
...     def foo(self):
...         print "Hi!"
...
>>>
>>> def bar(self):
...     print "Bork bork bork!"
...
>>>
>>> c = C()
>>> C.bar = bar
>>> c.bar()
Bork bork bork!
>>> c.foo()
Hi!
>>>

Il facilite également (pour autant que je sache) la mise en œuvre du runtime python.

13 votes

+1 pour Il s'agit de minimiser la différence entre méthodes et fonctions. Cette réponse devrait être acceptée

0 votes

C'est aussi à la racine de l'explication de Guido, très liée.

2 votes

Cela montre aussi qu'en Python, lorsque vous faites c.bar(), il vérifie d'abord les attributs de l'instance, puis il vérifie classe attributs . Ainsi, vous pouvez "attacher" une donnée ou une fonction (objets) à une classe à tout moment et vous attendre à y accéder dans son instance (c'est-à-dire que dir(instance) sera comment elle) . Pas seulement lorsque vous avez "créé" l'instance. C'est très dynamique.

59voto

bhadra Points 7255

Je suggère que l'on lise Le blog de Guido van Rossum sur ce sujet - Pourquoi le soi explicite doit rester .

Lorsqu'une définition de méthode est décorée, nous ne savons pas s'il faut lui donner automatiquement un paramètre 'self' ou non : le décorateur pourrait transformer la fonction en une méthode statique (qui n'a pas de 'self'), ou en une méthode de classe (qui a un drôle de 'self' qui fait référence à une classe au lieu d'une instance), ou il pourrait faire quelque chose de complètement différent (il est trivial d'écrire un décorateur qui implémente '@classmethod' ou '@staticmethod' en Python pur). Sans savoir ce que fait le décorateur, il n'y a aucun moyen de savoir s'il faut doter la méthode définie d'un argument 'self' implicite ou non.

Je rejette les astuces telles que l'utilisation d'une casse spéciale pour "@classmethod" et "@staticmethod".

16voto

Victor Noagbodji Points 133

Python ne vous oblige pas à utiliser "self". Vous pouvez lui donner le nom que vous voulez. Vous devez juste vous rappeler que le premier argument dans un en-tête de définition de méthode est une référence à l'objet.

0 votes

Par convention, il devrait cependant être "self" pour les instances ou "cls" lorsque des types sont impliqués (mmmm métaclasses).

6 votes

Cela oblige à mettre le soi comme premier paramètre dans chaque méthode, juste un texte supplémentaire qui n'a pas beaucoup de sens pour moi. D'autres langues fonctionnent très bien avec cela.

0 votes

Ai-je raison ? toujours le premier paramètre est une référence à l'objet.

2voto

ctcherry Points 15112

Une discussion sur le soi peut être trouvée dans ce fil de la liste de diffusion .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X