web-dev-qa-db-fra.com

Quand utilisez-vous «self» en Python?

Êtes-vous censé utiliser self pour référencer une fonction membre dans Python (dans le même module)?

Plus généralement, je me demandais quand il fallait utiliser self, pas seulement pour les méthodes mais aussi pour les variables.

31
Dark Templar

Ajouter une réponse parce que celle d'Oskarbi n'est pas explicite.

Vous utilisez self lorsque:

  1. Définition d'une méthode d'instance. Il est transmis automatiquement en tant que premier paramètre lorsque vous appelez une méthode sur une instance, et c'est l'instance sur laquelle la méthode a été appelée.
  2. Référencer une classe ou une instance d'attribut à l'intérieur d'une méthode d'instance. Utilisez-le pour appeler une méthode ou accédez à un nom (variable) sur l'instance sur laquelle la méthode a été appelée, depuis l'intérieur de cette méthode.

Vous n'utilisez pas self lorsque

  1. Vous appelez une méthode d'instance normalement. En utilisant l'exemple d'Oskarbi, si vous faites instance = MyClass(), vous appelez MyClass.my_method Comme instance.my_method(some_var) pas comme instance.my_method(self, some_var).
  2. Vous référencez un attribut de classe de à l'extérieur d'une méthode d'instance mais à l'intérieur de la définition de classe.
  3. Vous êtes à l'intérieur d'un méthode statique .

Ces choses à ne pas faire ne sont que des exemples de la non-utilisation de soi. Les dos sont quand vous devriez l'utiliser.

29
agf

Utilisez self pour faire référence aux variables et méthodes d'instance provenant d'autres méthodes d'instance. Mettez également self comme premier paramètre dans la définition des méthodes d'instance.

Un exemple:

class MyClass(object):

    my_var = None

    def my_method(self, my_var):
         self.my_var = my_var
         self.my_other_method()

    def my_other_method(self):
         # do something...
14
Oskarbi
  1. Il y a rien 'spécial' sur le nom self. C'est le nom préféré par convention par Pythonistas, pour indiquer ce que ce paramètre devrait contenir.

  2. L'exécution Python transmettra une valeur "self" lorsque vous appelez une méthode d'instance sur une instance, que vous la fournissiez délibérément ou non. Cela entraînera généralement une erreur facilement diagnostiquée/comprise ( car la fonction sera appelée avec le mauvais nombre de paramètres), mais l'utilisation de *args peut conduire à des erreurs de type un peu plus étranges.

  3. Le paramètre est transmis implicitement lorsque vous appelez une méthode d'instance sur une instance. Il contient l'instance sur laquelle vous appelez la méthode. Donc, vous ne mentionnez pas self dans l'appel de fonction car (a) comme indiqué ci-dessus, cela n'aurait aucun sens (il n'y a pas de self dans la portée, en général, et self n'est pas un mot-clé ou un nom spécial ou quoi que ce soit); (b) vous avez déjà indiqué l'instance à utiliser (en écrivant my_instance.).

  4. Vous pouvez bien sûr appeler explicitement une méthode d'instance en y accédant depuis la classe. Dans ce cas, vous devrez passer explicitement l'instance comme premier paramètre. Vous ne voulez généralement pas faire cela. Et vous en particulier ne voulez pas écrire de code qui considère la possibilité que le premier paramètre soit autre chose qui a été explicitement passé de cette façon. Cela revient à vérifier if (this == null) en C++: vous ne le faites pas, car si cela peut éventuellement signifier quelque chose , alors le le code d'appel est faux, moralement sinon légalement. (Au moins en Python vous n'aurez pas de problèmes avec un comportement indéfini, mais c'est toujours moralement mauvais.)

  5. Dans la méthode d'instance, puisque self est un paramètre auquel l'instance a été affectée en tant que valeur, vous pouvez écrire self.whatever Pour accéder aux attributs de l'instance. Contrairement à certains autres langages de style 'implicite this', les noms d'attribut sont pas implicitement "à portée".

  6. Il n'y a pas d'autre cas d'utilisation pour self, car là encore ce n'est pas un nom spécial, et c'est le seul but spécifique que la convention de dénomination aborde. Si vous aviez besoin d'accéder à une "variable" (vraiment un attribut) à partir d'un autre module, vous utiliseriez le nom du module. Si vous vouliez accéder à l'un à partir du module actuel, aucun préfixe n'est nécessaire, ou vraiment possible d'ailleurs. (Eh bien, vous pourriez le rechercher explicitement dans le dict renvoyé par globals(), mais s'il vous plaît ne faites pas cela.)

4
Karl Knechtel

Par exemple, pour les variables et les méthodes, il est obligatoire d'utiliser self à tout moment.

3
lc2817