
Attributs Python : comprendre comment ils fonctionnent 🐍
Les attributs sont le fondement du modèle objet de Python, mais la plupart des débutants (et même de nombreux développeurs intermédiaires) les utilisent intuitivement sans comprendre ce qui se passe "sous le capot". Résultat : un comportement imprévisible du code, une consommation de mémoire excessive et des API spaghetti.
Décortiquons les nuances 👇
1️⃣ Ordre de recherche (MRO)
Python fonctionne selon le principe : d'abord l'objet, ensuite la classe.
Lorsque vous accédez à
obj.attr, l'interpréteur regarde d'abord dans obj.__dict__. S'il ne trouve pas, il va dans Class.__dict__.Si vous écrivez accidentellement quelque chose dans
obj.attr, vous créez un attribut d'instance qui masquera l'attribut de classe.class Hero:
weapon = "Sword"
h = Hero()
h.weapon = "Gun" # Maintenant h a sa propre arme, la classe a toujours l'épéeCe n'est pas un bug, c'est une fonctionnalité, mais contrôlez-la. Si vous voulez modifier l'attribut pour tous, adressez-vous à la classe.
2️⃣
__dict__ vs __slots__Par défaut, chaque objet a
__dict__ — une table de hachage (dictionnaire) où sont stockés les attributs. C'est flexible, mais coûteux en mémoire.Si vous créez des millions d'objets du même type, utilisez
__slots__.🔵Ce que cela apporte : On empêche la création de
__dict__ pour l'instance, en fixant rigidement l'ensemble des attributs en mémoire (comme un tableau).🔵Bénéfice : Moins 25-30% de consommation mémoire et un accès légèrement plus rapide.
🔵Coût : Vous perdez la possibilité dynamique d'ajouter de nouveaux attributs à la volée.
3️⃣ L'illusion de l'encapsulation
En Python, il n'y a pas de champs "privés". Du tout.
Les constructions comme
__attribute ne sont pas une protection des données, mais un name mangling (altération de nom). Python renomme simplement la variable en _ClassName__attribute pour éviter de l'écraser accidentellement dans les classes filles.Si vous écrivez
__ en espérant que personne n'accède à vos données, sachez que quiconque sait utiliser dir() verra tout. Écrire _private (un seul underscore) signifie "ne touche pas, c'est une API interne". C'est une question de culture, pas de compilateur.Vous voulez cacher des données ? Utilisez un seul underscore
_ uniquement comme signal à vos collègues : "Ne touche pas à ça, c'est l'interne". 4️⃣ @property : le getter éthique
Ne faites jamais en Python des getters à la Java (
get_value(), set_value()). Si vous avez besoin de logique lors de l'accès à un attribut, utilisez @property.@property permet de transformer une méthode en attribut. Vous conservez une API propre (accès par point), mais sous le capot vous pouvez valider les données, journaliser l'accès ou calculer des valeurs à la volée. class DataStorage:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, new_val):
if not isinstance(new_val, int):
raise ValueError("Seulement int, mon cher")
self._value = new_valAinsi vous conservez une interface propre :
obj.value = 10 semble aussi simple que de travailler avec un champ ordinaire, mais vous contrôlez ce qui y est écrit.Quels autres endroits "magiques" de Python vous posent question ? Balancez dans les commentaires, on décortique. 👇
#anatomie_du_python
Commentaires
0Aucun commentaire pour le moment.