Les attributs et les méthodes privés dans la programmation orienté objet ne sont accessibles que par les membres de la classe.

attributs et les méthodes privés

Vous avez certainement déjà rencontré ces termes en Python : public, privé et protégé. Ainsi que des noms avec un trait ou deux traits de soulignements au début ou à la fin.

Les attributs publics sont accessibles à tout objet utilisant l’opérateur point.

Commençons par un exemple simple pour vous rafraîchir un peu la mémoire.

Construisons une classe de base.

class MaClass:
  def __init__(self):
    self.num = 1

  def get_num(self):
    return self.num

Dans notre classe, la méthode __init__ définit un attribut num qui est initialisé avec la valeur 1 et une méthode get_num qui renvoie la valeur de num.

Maintenant, accédons et modifions la valeur de num.

obj = MaClass() # créer une instance de classe
# afficher la valeur de l'attribut num
print(obj.num)
print(obj.get_num())

L’exécution du code.

1
1

Nous allons modifier la valeur de l’attribut num.

obj.num = 3
# accéder à la nouvelle valeur de l'attribut num
print("La nouvelle valeur de num : ", obj.num)
print("La nouvelle valeur de num : ", obj.get_num())

L’exécution du code.


La nouvelle valeur de num :  3
La nouvelle valeur de num :  3

Comme vous pouvez le constater, nous avons facilement modifié la valeur de num de 1 à 3. En fait, ceci est possible puisque nous avons accès à l’attribut num de l’extérieur.
Mais comment faire pour masquer cet attribut aux utilisateurs externes ?

Comment utiliser les attributs et les méthodes privés en Python ?

Pour rendre les attributs et les méthodes privés en Python, préfixez le nom avec un seul trait de soulignement.

Reprenons l’exemple précédent.

class MaClass:
  def __init__(self):
    self._num = 1

  def _get_num(self):
    return self._num

Essayons d’accéder à cet attribut privé.

obj = MaClass() # créer une instance de classe
# afficher la valeur de l'attribut _num
print(obj._num)
print(obj._get_num())

Exécution code.

1
1

Mais ça n’a rien de privé !

En fait, l’accès aux attributs et aux méthodes privés n’est pas réellement ce que vous croyez ou ce que vous avez peut-être vu dans d’autres langages de programmation.

En réalité, quand nous disons que les attributs et les méthodes qui commencent par un seul trait de soulignement sont privés, ce n’est qu’une convention. Python ne prend pas en charge l’encapsulation.

Même si l’encapsulation n’est pas appliquée, cela ne signifie pas que vous devez accéder aux attributs et méthodes privés. Ne le faites pas parce que vous n’êtes pas censé le faire.

En plus de cela, si vous concevez votre propre classe ou bibliothèque, et que vous voulez indiquer aux utilisateurs de votre bibliothèque qu’ils ne doivent pas accéder à des attributs ou des méthodes spécifiques, préfixez les noms des variables avec un seul trait de soulignement.

Et selon la documentation Python, « …Il doit être vu comme un détail pouvant faire l’objet de modifications futures sans préavis ».

Qu’est-ce que l’encapsulation ?

L’encapsulation est l’un des quatre concepts fondamentaux de la programmation orientée objet, qui sont l’abstraction, l’encapsulation, l’héritage et le polymorphisme. L’encapsulation est le regroupement de données et de méthodes dans une classe afin que vous puissiez masquer les informations et restreindre l’accès de l’extérieur. Ce concept permet à une classe de protéger son état interne de l’extérieur.

L’encapsulation agit comme une couche de protection qui empêche l’accès aux données encapsulées par un code défini en dehors de la classe dans laquelle les données encapsulées sont définies. Donc, l’encapsulation assure la sécurité en cachant les données du monde extérieur.

Préfixation avec des doubles traits de soulignement

Continuons avec notre classe précédente et définissons l’attribut num et la méthode get_num(), mais cette fois en utilisant des doubles traits de soulignement au lieu d’un seul.

class MaClass:
  def __init__(self):
    self.__num = 1

  def __get_num(self):
    return self.__num
obj = MaClass() # créer une instance de classe
# afficher la valeur de l'attribut __num
print(obj.__num)
print(obj.__get_num())

Exécution du code.

AttributeError: 'MaClass' object has no attribute '__num'

Python ne trouve pas l’attribut __num, bien qu’il est défini dans notre classe.

Essayons de chercher dans l’espace de nom de la classe.

obj = MaClass()
print(dir(obj))
['_MaClass__get_num', '_MaClass__num', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

En fait, Python a renommé la variable __num en _MyClass__num et la méthode __get_num en _MyClass__get_num.

Ce comportement de transformation des noms d’attributs et des méthodes est appelé name mangling.

Name Mangling ou cette modification « brutale » du nom rend plus difficile l’accès aux variables depuis l’extérieur de la classe, mais elles sont toujours accessible via _MaClass__num et _MaClass__get_num.

# afficher la valeur de l'attribut num
print(obj._MaClass__num)
print(obj._MaClass__get_num())

Donc, en dehors de la classe, vous devrez utiliser le nom modifié de l’attribut, mais à l’intérieur de la classe, vous pouvez toujours accéder à l’attribut.

Avant de terminer, nous allons profiter pour apprendre certaines autre utilisations courantes du trait de soulignement en plus de ce que nous avons vu plus haut et des méthodes spéciales.

Pour des variables inutilisées

Un seul trait de soulignement est un nom de variable temporaire qui ne sera pas réutilisée.

for _ in range(3):
    print('Python')
Python
Python
Python

De plus, un trait de soulignement seul est une variable spéciale qui représente le résultat de la dernière expression évaluée.

>>> 5 + 5
10
>>> _
10

Éviter les conflits avec des mots-clés

Parfois on utilise un mot-clé Python comme class, type, list, comme nom de variable, ce qui nous donne une SyntaxError.
Pour éviter les conflits des noms, ajoutez un seul trait de soulignement au nom de la variable.


0 commentaire

Laisser un commentaire

Emplacement de l’avatar

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *