Lesson explanation
@propertyAfter this lesson, you will be able to:
@property.Python does not use Java-style private fields in the same way. A name such as _balance signals internal use by convention; it is not strong access protection. A property lets external code read account.balance while a method computes or validates the value behind the scenes.
Define a getter with @property. For writable properties, add a setter with @property_name.setter. Inside a setter, write to the backing field (self._balance), not to the property name (self.balance), or the setter calls itself repeatedly.
A property can also be read-only: omit its setter. Calculated properties should be consistent with current object state. Use properties for meaningful validation or computation, not just to reproduce verbose getters and setters from Java.
_status stores the value, and status offers a clean reading interface.
class Task:
def __init__(self, status):
self._status = status
@property
def status(self):
return self._status
print(Task("queued").status)Output:
queuedThe setter rejects negative values while preserving the old reading.
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)Output:
3No separate remaining field must be synchronized.
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)Output:
65Use attribute access instead of parentheses; a property getter runs automatically.
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}")Output:
Ready: True| Need | Use |
|---|---|
| Internal field convention | self._value |
| Public read access | @property getter |
| Validated write access | @value.setter |
| Calculated value | Read-only property without setter |
| Avoid recursive setters | Assign backing field, not self.value |
obj.total()) instead of reading it (obj.total).self.value = ... inside the setter for value._value cannot be accessed outside the class; it is a convention.