137 votes

Trait de soulignement vs trait de soulignement Double avec des variables et des méthodes

Quelqu'un a été assez gentil pour m'expliquer qu' __méthode() mangles, mais au lieu de prendre la peine de lui plus depuis qu'il y a beaucoup d'autres personnes qui ont besoin d'aide, je me demandais si quelqu'un pourrait décrire les différences plus loin.

Par exemple je n'ai pas besoin d'amputation, mais n' _ séjour privé de sorte que quelqu'un ne pouvait pas faire d'instance._method()? Ou est-il juste de remplacer une variable par qui la rend unique? Je n'ai pas besoin de mes méthodes internes "caché", mais depuis qu'ils sont spécifiques à l'utilisation je ne veux pas être utilisé en dehors de la classe.

258voto

nmichaels Points 21955

À partir de la PEP 8:

- _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
  import *" does not import objects whose name starts with an underscore.

- single_trailing_underscore_: used by convention to avoid conflicts with
  Python keyword, e.g.

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

- __double_leading_underscore: when naming a class attribute, invokes name
  mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

- __double_leading_and_trailing_underscore__: "magic" objects or
  attributes that live in user-controlled namespaces.  E.g. __init__,
  __import__ or __file__.  Never invent such names; only use them
  as documented.

Aussi, à partir de David Goodger du Code Comme un Pythonista:

Attributs: interface, _internal, __privés

Mais essayez d'éviter l' __privés forme. Je ne l'utilise jamais. Faites-moi confiance. Si vous l'utiliser, vous le regretterez plus tard.

Explication:

Des personnes venant du C++/Java de fond sont particulièrement sujettes à l' la surutilisation de/un mauvais usage de cette "fonctionnalité". Mais _privés noms ne fonctionnent pas même façon comme en Java ou en C++. Ils ont juste déclencher une amputation des noms dont le but est d'empêcher les collisions d'espace de noms dans les sous-classes: MyClass._private devient juste MyClass.MyClass_private. (Notez que même ce chiffre se décompose pour les sous-classes avec le même nom que le super-classe, par exemple, les sous-classes dans les différents modules.) Il est possible de accès __privés des noms à partir de l'extérieur de leur classe, juste gênant et fragile (il ajoute une dépendance sur le nom exact de la super-classe).

Le problème, c'est que l'auteur d'une classe, on peut légitimement penser "ce l'attribut ou le nom de la méthode doit être privé, uniquement accessible à partir de cette définition de la classe" et l'utilisation de l' __privés de la convention. Mais plus tard, un utilisateur de cette classe peut faire une sous-classe qui a légitimement besoin d' l'accès à ce nom. Donc, soit la super-classe doit être modifié (ce qui peut être difficile ou impossible), ou de la sous-classe code de utiliser manuellement les noms déformés (ce qui est laid et fragile, au mieux).

Il y a un concept en Python: "nous sommes tous des adultes consentants ici". Si vous utilisez l' __privés forme, qui êtes-vous protégeant de l'attribut? Il est de la responsabilité des sous-classes pour utiliser les attributs de superclasses correctement, et il est de la responsabilité des super-classes de document de leurs attributs correctement.

Il est préférable d'utiliser la seule pointe-de souligner la convention, _internal. "Ce n'est pas le nom mutilé; il indique juste à d'autres de "faire attention à cela, c'est une mise en œuvre interne de détail; de ne pas y toucher si vous ne comprenez pas complètement". C'est seulement une convention, bien.

118voto

Ned Batchelder Points 128913

Un seul trait de soulignement est une convention qui signifie, "Vous ne devriez pas l'utiliser." Il ne fait rien pour empêcher quelqu'un de l'aide de l'attribut.

Un double trait de soulignement de modifier le nom de l'attribut, de sorte que deux classes dans une hiérarchie d'héritage peuvent utiliser le même nom d'attribut, et ils ne seront pas en collision.

11voto

Cat Plus Plus Points 53385

Il n'y a pas de contrôle d'accès en Python. Vous pouvez accéder à tous les attributs d'une classe, et qui comprend les noms déformés ( _class__variable). Concentrez-vous sur votre code et de l'API au lieu d'essayer de protéger les développeurs d'eux-mêmes.

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