ProgrammationDéveloppeur Python

Qu'est-ce que les variables et méthodes protégées et privées en Python, comment l'encapsulation est-elle réalisée, et dans quelle mesure Python protège-t-il réellement l'état interne de l'objet ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

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 :

  • Underscore simple — convention : "ne touche pas" en dehors de la classe et de la hiérarchie.
  • Underscore double — name mangling : le nom de la classe est ajouté à la variable dans le bytecode.
  • Python n'interdit pas l'accès, mais le complique — c'est une convention, pas une restriction stricte.

Questions pièges.

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.

Erreurs typiques et anti-patterns

  • Attendre une protection complète grâce à un double underscore.
  • Utilisation de méthodes privées dans les héritiers, ce qui nuit à la lisibilité et à l'extensibilité.
  • Application massive de double underscores là où un simple underscore est suffisant.

Exemple de la vie réelle

Cas négatif

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:

  • Cacher formellement l'attribut de l'auto-complétion.

Inconvénients:

  • Illusion trompeuse de la confidentialité.
  • Possibilité de briser les invariants de la classe.

Cas positif

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:

  • Lisibilité, respect des conventions.
  • Facilité de maintenance du code.

Inconvénients:

  • Absence de confidentialité stricte : un développeur malavisé peut accéder en violant les accords.