The Python @property decorator creates a property object from a getter method, exposing controlled access to hidden instance state through ordinary attribute syntax. Reading target.title calls the getter, while a property without a setter is read-only. A property may also calculate a value at access time instead of returning a stored variable. section 2.3.1
Read-only and calculated properties
A Book stores _title, _last, and _first while exposing title, last, and first through @property methods. Code can write target.last to read the author’s surname, but target.last = "Smith" raises an error. A Circle can instead expose circumference and area as properties calculated from _radius whenever accessed. section 2.3.1
Add a setter when callers must modify state without depending on its implementation. The @price.setter decorator attaches a mutator to the existing price property, allowing item.price = 10.75 to validate and update _price while preserving the same public interface. The class can later obtain the price from another hidden source without changing callers. section 5.2
Use properties to preserve a stable public interface while controlling state access:
- Expose private instance variables through getter properties rather than direct external access. section 2.3.1
- Attach a setter when updates require validation, such as rejecting a nonpositive price. section 5.2
- Keep callers dependent on the property interface, not on whether state comes from an instance variable or a database lookup. section 5.2
Listing 5.1 (Program 5.1 DemeterItem): item.py
class Item:
def __init__(self, name, weight, price):
self._name = name #1
self._weight = weight #1
self._price = price #1
@property
def name(self): return self._name #2
@property
def weight(self): return self._weight #2
@property
def price(self): return self._price #2
@price.setter
def price(self, new_price): #3
assert new_price > 0
self._price = new_price
Inspect a complete Item implementation with getter properties and a validating price setter. section 5.2

