How do properties and descriptors work in Python?

· Category: Python Programming

Short answer

The @property decorator lets you define methods that are accessed like attributes. It supports getter, setter, and deleter logic, allowing you to validate data or compute values on the fly without changing the public interface.

Steps

  1. Define a method with @property to create a getter.
  2. Define a setter with @name.setter.
  3. Optionally define a deleter with @name.deleter.
class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("Below absolute zero")
        self._celsius = value

    @property
    def fahrenheit(self):
        return self._celsius * 9 / 5 + 32

t = Temperature(25)
print(t.fahrenheit)
t.celsius = 100
print(t.fahrenheit)

Tips

  • Use properties to transition from simple public attributes to managed access without breaking existing code.
  • Descriptors (classes implementing __get__, __set__, and __delete__) are the underlying mechanism; property is a built-in descriptor.
  • For read-only attributes, define only the getter.

Common issues

  • Naming the property and the backing field the same causes infinite recursion.
  • Setting a property without a setter raises an AttributeError.
  • Properties add a small overhead compared to direct attribute access, which is usually negligible.