Historique de la question
Dans la programmation orientée objet classique, l'encapsulation est réalisée par la limitation de l'accès aux données internes. Dans la plupart des langages, il existe des modificateurs d'accès stricts. En Python, le principe est "nous sommes tous des adultes" — il n'y a pas de confidentialité stricte.
Problème
Les développeurs confondent les attributs et méthodes protégés (_protected) et privés (__private) en Python, pensant que le "double underscore" assure une protection complète, ou considérant qu'il n'y a pas de protection du tout.
Solution
Python met en œuvre des conventions : un underscore simple _var — protégé, un double __var — privé (le nom est soumis à du mangling). L'accès à un tel attribut ou méthode est possible, mais plus difficile : il se nomme _ClassName__var.
Exemple de code:
class Example: def __init__(self): self._protected = 1 # protégé self.__private = 2 # privé (name mangling) ex = Example() print(ex._protected) # 1 #print(ex.__private) # AttributeError print(ex._Example__private) # 2 (name mangling)
Caractéristiques clés :
Peut-on accéder à un champ "privé" avec double underscore via une instance?
Oui, via le mangling : _ClassName__var. Donc, les données sont accessibles, simplement de manière implicite.
Comment se comportera une méthode/attribut privé lors de l'héritage ?
Le name mangling empêche les héritiers de redéfinir accidentellement les éléments privés des parents, mais l'accès peut être obtenu via _ParentClass__attr. Les méthodes avec double underscore ne sont pas "visibles" de l'extérieur de la classe héritière.
class A: def __foo(self): print("A") class B(A): def bar(self): # self.__foo() — erreur self._A__foo() # fonctionne
Y a-t-il une pleine confidentialité en Python comme en JVM/C++ ?
Non. Tout est basé sur des conventions et du mangling. Il est impossible de protéger complètement les données, car Python permet dynamiquement d'accéder à n'importe quel attribut.
Dans une grande bibliothèque, un utilisateur a essayé de changer un attribut privé via un double underscore, pensant que c'était un "secret" — mais via _ClassName__var, le changement a quand même eu lieu.
Avantages:
Inconvénients:
Dans le projet, il a été convenu d'utiliser un underscore simple pour les champs internes et de ne pas les toucher en dehors de la classe. Une propriété a été ajoutée pour un accès sécurisé.
Avantages:
Inconvénients: