Duplicate possible:
signification d'un simple et double soulignement avant un nom d'objet en Python
Lequel dois-je utiliser _foo (un trait de soulignement) ou __bar (double soulignement) pour les membres privés et les méthodes en Python?
Veuillez noter qu’il n’existe pas de méthode privée en Python. Le double soulignement n'est qu'un nom:
>>> class A(object):
... def __foo(self):
... pass
...
>>> a = A()
>>> A.__dict__.keys()
['__dict__', '_A__foo', '__module__', '__weakref__', '__doc__']
>>> a._A__foo()
Ainsi donc __
Le préfixe est utile lorsque vous avez besoin de changer, par exemple pour ne pas entrer en conflit avec les noms situés en haut ou en dessous de la chaîne d'héritage. Pour d'autres utilisations, un soulignement simple serait mieux, à mon humble avis.
EDIT, concernant la confusion sur __
, PEP-8 est tout à fait clair à ce sujet:
Si votre classe doit être sous-classée et que vous ne souhaitez pas que les sous-classes soient utilisées, pensez à les nommer avec des traits de soulignement doubles et aucun tiret de fin. Ceci appelle l'algorithme de changement de nom de Python, où le nom de la classe est mutilé dans le nom de l'attribut. Cela permet d'éviter les conflits de noms d'attributs si les sous-classes contiennent par inadvertance des attributs portant le même nom.
Note 3: Tout le monde n'aime pas les noms malins. Essayez de trouver un équilibre entre la nécessité d’éviter les conflits de noms accidentels et l’utilisation potentielle par des appelants expérimentés.
Donc, si vous ne vous attendez pas à ce que la sous-classe redéfinisse accidentellement sa propre méthode avec le même nom, ne l'utilisez pas.
Le double soulignement. Il modifie le nom de manière à ce qu'il ne soit pas accessible simplement via __fieldName
de l’extérieur de la classe, c’est ce avec quoi vous voulez commencer si elles sont privées. (Bien que ce ne soit pas encore très difficile d'accéder au terrain.)
class Foo:
def __init__(self):
self.__privateField = 4;
print self.__privateField # yields 4 no problem
foo = Foo()
foo.__privateField
# AttributeError: Foo instance has no attribute '__privateField'
Il sera accessible via _Foo__privateField
au lieu. Mais ça crie "JE SUIS PRIVÉ NE ME TOUCHEZ PAS", ce qui est mieux que rien.
Double soulignement. Cela modifie le nom. La variable est toujours accessible, mais c'est généralement une mauvaise idée de le faire.
Utilisez des traits de soulignement simples pour les semi-privés (indique à python "ne modifiez cela que si vous devez absolument")) et double pour un comportement totalement privé.