Property
Properties and descriptors are Python's mechanism for managed attributes. They allow you to define attributes that execute code on access, assignment, or deletion, enabling computed attributes and validation. The guide walks through The @property Decorator, Setter & Deleter, Computed Properties, Descriptor Protocol, When to Use Properties. `@property` marks a method as a getter: `@property; def name(self) -> str:`. Access it as an attribute without parentheses: `obj.name`. This is the simplest way to create computed or validated read-only attributes. `@name.setter` defines assignment behavior: `@name.setter; def name(self, value): self._name = value`. `@name.deleter` defines deletion behavior. The pattern stores the actual value in a private attribute (conventionally `_name`) and provides logic in the property methods. Properties can compute values dynamically from other attributes: `@property; def area(self): return self.width * self.height`. Computed properties are recalculated on every access. Cache expensive computations with `@functools.cached_property` for read-only computed attributes. The guide is organized into 5 sections that build on each other, each pairing a prose explanation with runnable code.