Explication de la leçon
@propertyAprès cette leçon, tu seras capable de :
@property.Python n'utilise pas les champs private à la manière de Java. Un nom tel que _balance signale un usage interne par convention ; ce n'est pas une protection d'accès stricte. Une propriété permet au code externe de lire account.balance tandis qu'une méthode calcule ou valide la valeur en coulisses.
Définis un getter avec @property. Pour les propriétés accessibles en écriture, ajoute un setter avec @property_name.setter. À l'intérieur d'un setter, écris dans le champ sous-jacent (self._balance), et non dans le nom de la propriété (self.balance), sinon le setter s'appelle lui-même en boucle infinie.
Une propriété peut également être en lecture seule : omet simplement son setter. Les propriétés calculées doivent rester cohérentes avec l'état actuel de l'objet. Utilise les propriétés pour des validations ou calculs pertinents, et non pour reproduire des getters et setters verbeux de Java.
_status stocke la valeur, et status offre une interface de lecture propre.
class Task:
def __init__(self, status):
self._status = status
@property
def status(self):
return self._status
print(Task("queued").status)Sortie :
queuedLe setter rejette les valeurs négatives tout en conservant l'ancienne mesure.
class Counter:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, next_value):
if next_value >= 0:
self._value = next_value
counter = Counter(3)
counter.value = -8
print(counter.value)Sortie :
3Aucun champ remaining séparé ne doit être synchronisé.
class Quota:
def __init__(self, limit, used):
self.limit = limit
self.used = used
@property
def remaining(self):
return self.limit - self.used
quota = Quota(100, 35)
print(quota.remaining)Sortie :
65Utilise l'accès direct par attribut plutôt que des parenthèses ; un getter de propriété s'exécute automatiquement.
class Release:
def __init__(self, passed):
self.passed = passed
@property
def ready(self):
return self.passed > 0
release = Release(2)
print(f"Ready: {release.ready}")Sortie :
Ready: True| Besoin | Utilisation |
|---|---|
| Convention de champ interne | self._value |
| Accès en lecture public | Getter @property |
| Accès en écriture validé | @value.setter |
| Valeur calculée | Propriété en lecture seule sans setter |
| Éviter les setters récursifs | Affecter le champ sous-jacent, pas self.value |
obj.total()) au lieu de la lire (obj.total).self.value = ... à l'intérieur du setter pour value._value ne peut pas être accédé en dehors de la classe ; c'est une convention.