web-dev-qa-db-fra.com

Pourquoi certaines fonctions ont-elles un trait de soulignement "__" avant et après le nom de la fonction?

Cela semble se produire souvent, et je me demandais si c'était une exigence du langage Python, ou simplement une question de convention?

Aussi, quelqu'un pourrait-il nommer et expliquer quelles fonctions ont tendance à avoir des traits de soulignement et pourquoi (__init__, par exemple)?

353
Chuck Testa

À partir du Guide de style pour le code Python Python PEP 8 :

Descriptif: Styles de nommage

Les formes spéciales suivantes utilisant des tirets bas et des tirets bas sont reconnues (elles peuvent généralement être combinées avec toute convention de cas):

  • _single_leading_underscore: indicateur faible "usage interne". Par exemple. from M import * n'importe pas d'objets dont le nom commence par un trait de soulignement.

  • single_trailing_underscore_: utilisé par convention pour éviter les conflits avec le mot clé Python, par exemple.

    Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore: lorsque vous nommez un attribut de classe, invoquez le changement de nom (dans la classe FooBar, __boo devient _FooBar__boo; voir ci-dessous).

  • __double_leading_and_trailing_underscore__: objets ou attributs "magiques" qui résident dans des espaces de noms contrôlés par l'utilisateur. Par exemple. __init__, __import__ ou __file__. Ne jamais inventer de tels noms; utilisez-les uniquement comme documenté.

Notez que les noms avec des tirets bas et des tirets bas sont essentiellement réservés à Python lui-même: "N'inventez jamais de tels noms; utilisez-les uniquement comme documenté".

486
Michael Burr

Les autres répondants ont raison de décrire les traits de soulignement avant et arrière comme une convention de dénomination pour les méthodes "spéciales" ou "magiques".

Bien que vous puissiez appeler ces méthodes directement ([10, 20].__len__() par exemple), la présence des traits de soulignement indique que ces méthodes sont censées être appelées indirectement (par exemple, len([10, 20]) La plupart des opérateurs python ont une méthode "magique" associée (par exemple, a[x] est le moyen habituel d'appeler a.__getitem__(x)).

49
Raymond Hettinger

Les noms entourés de doubles tirets bas sont "spéciaux" pour Python. Ils sont répertoriés dans Référence du langage Python, section 3, "Modèle de données" .

14

En fait, j'utilise les noms de méthodes _ lorsque je dois faire la différence entre les noms de classes parent et enfant. J'ai lu des codes qui utilisaient cette façon de créer des classes parent-enfant. À titre d'exemple, je peux fournir ce code: 

class ThreadableMixin:
   def start_worker(self):
       threading.Thread(target=self.worker).start()

   def worker(self):
      try:
        self._worker()
    except tornado.web.HTTPError, e:
        self.set_status(e.status_code)
    except:
        logging.error("_worker problem", exc_info=True)
        self.set_status(500)
    tornado.ioloop.IOLoop.instance().add_callback(self.async_callback(self.results))

...

et l'enfant qui a une méthode _worker 

class Handler(tornado.web.RequestHandler, ThreadableMixin):
   def _worker(self):
      self.res = self.render_string("template.html",
        title = _("Title"),
        data = self.application.db.query("select ... where object_id=%s", self.object_id)
    )

...

5
Omadbek Onorov

Cette convention est utilisée pour des variables ou méthodes spéciales (appelées «méthode magique») telles que __init__, len . Ces méthodes fournissent des fonctionnalités syntaxiques spéciales ou font des choses spéciales. 

Par exemple, fichier indique l'emplacement du fichier Python, eq est exécuté lors de l'expression d'une expression == b. 

Bien sûr, un utilisateur peut créer une méthode spéciale personnalisée, ce qui est un cas très rare, mais peut souvent modifier les méthodes spéciales intégrées. (Par exemple, vous devez initialiser la classe avec init qui sera exécutée d’abord lors de la création d’une instance de classe.)

   class A:
      def __init__(self, a): # use special method '__init__' for initializing
        self.a = a
      def __custom__(self): # custom special method. you might almost do not use it
        pass
0
Shagun Pruthi

Double soulignement arrière (recherche de nom)/D'après les documents Python

Tout identificateur de la forme __spam (au moins deux traits de soulignement principaux, au plus un trait de soulignement de fin) est textuellement remplacé par _classname__spam, nom de classe étant le nom de la classe en cours, avec suppression du trait de soulignement. Cette modification est effectuée sans tenir compte de la position syntaxique de l'identificateur. Elle peut donc être utilisée pour définir des variables d'instance et de classe privées, des méthodes, des variables stockées dans des globales et même des variables stockées dans des instances. privé à cette classe sur des instances d'autres classes.

La gestion des noms a pour but de donner aux classes un moyen simple de définir des variables et des méthodes d’instance «privées», sans avoir à s’inquiéter des variables d’instance définies par des classes dérivées, ni du fauchage de variables d’instance par un code extérieur à la classe. Notez que les règles de manipulation sont principalement conçues pour éviter les accidents; il est toujours possible pour une âme déterminée d'accéder ou de modifier une variable considérée comme privée.

0
Arefe