PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

Attributs privés en Python

samedi 21 juin 2014 à 03:15

Tout est accessible en Python. Il n’y a pas de variables privées.

Quand on veut une variable à usage interne, la convention est de la nommer avec un underscore devant :

class Monique:
    def __init__(self):
        self._private = "lessons"

Ça n’empêche rien, mais les devs savent qu’il faut éviter d’utiliser cette variable car elle ne fait pas partie de l’API publique de la classe, et l’implémentation pourrait changer plus tard.

Comme self, c’est une convention forte puisque la plupart des libs de completion du code la prennent en compte.

Il existe une fonctionalité moins connue, qui fait que quand on utilise deux underscores, accéder directement à la variable lève un AttributeError:

class Monique:
    def __init__(self):
        self.__private = "lessons"
 
m = Monique()
print(m.__private)
AttributeError: 'Monique' object has no attribute '__private'

Du coup, quelques rares personnes ont utilisé cette feature pour émuler des attributs privés, ignorant le fait qu’on vous dit partout sur la toile que tout est accessible en Python.

C’est une mauvaise idée.

C’est une mauvaise idée car si votre objectif est la sécurité, ça ne sert à rien puisque votre variable est accessible de tas de manières détournées différentes. Par exemple :

print(m.__dict__['_Monique__private'])
# lessons
m.__dict__['_Monique__private'] = None
print(m.__dict__['_Monique__private'])
# None

C’est une mauvaise idée car si votre objectif est de créer une API publique, un seul underscore suffit.

Enfin c’est une mauvaise idée car si vous fournissez une lib qui ne correspond pas à un besoin, quelqu’un peut toujours contourner le problème en monkey patchant votre code le temps que vous trouviez une solution plus propre. En rendant la variable “privée”, vous rendez ceci plus difficile, sans le rendre impossible. Tout le monde y perd.

flattr this!