Advanced Properties
Property decorators, getters/setters, and computed properties.
Overview
Master property patterns.
Property Decorators
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):
return 3.14159 * self._radius ** 2
@property
def circumference(self):
return 2 * 3.14159 * self._radius
c = Circle(5)
print(c.area) # 78.53975
c.radius = 10
print(c.area) # 314.159
Computed Properties
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
self._celsius = value
@property
def fahrenheit(self):
return self._celsius * 9/5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
self._celsius = (value - 32) * 5/9
@property
def kelvin(self):
return self._celsius + 273.15
@kelvin.setter
def kelvin(self, value):
self._celsius = value - 273.15
t = Temperature(100)
print(t.fahrenheit) # 212.0
print(t.kelvin) # 373.15
Cached Properties
from functools import cached_property
class DataAnalyzer:
def __init__(self, data):
self.data = data
@cached_property
def mean(self):
print("Computing mean...")
return sum(self.data) / len(self.data)
@cached_property
def std_dev(self):
print("Computing std_dev...")
variance = sum((x - self.mean) ** 2 for x in self.data) / len(self.data)
return variance ** 0.5
analyzer = DataAnalyzer([1, 2, 3, 4, 5])
print(analyzer.mean) # Computes
print(analyzer.mean) # Uses cached value
print(analyzer.std_dev) # Computes (uses cached mean)
Practice
Implement a property-based validation system.