patternpythonModeratepending
Python descriptors and property patterns
Viewed 0 times
propertydescriptorset_namecached_propertygetter setter
Problem
Need computed properties, validation on attribute assignment, or custom attribute access behavior in Python classes.
Solution
From simple property to full descriptors:
# 1. Simple property
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError('Radius cannot be negative')
self._radius = value
@property
def area(self): # Read-only computed property
import math
return math.pi * self._radius ** 2
# 2. Reusable descriptor for validation
class Positive:
def __set_name__(self, owner, name):
self.name = name
self.private = f'_{name}'
def __get__(self, obj, objtype=None):
if obj is None:
return self
return getattr(obj, self.private, None)
def __set__(self, obj, value):
if value < 0:
raise ValueError(f'{self.name} must be positive, got {value}')
setattr(obj, self.private, value)
class Rectangle:
width = Positive() # Reusable!
height = Positive() # Reusable!
def __init__(self, width, height):
self.width = width # Validation happens here
self.height = height
# 3. Cached property (compute once)
from functools import cached_property
class DataSet:
@cached_property
def stats(self):
# Expensive computation, cached after first access
return compute_statistics(self.data)Why
Properties and descriptors provide controlled attribute access without changing the API. Users write obj.x instead of obj.get_x(), keeping the interface clean.
Context
Python classes needing computed or validated attributes
Revisions (0)
No revisions yet.