Summary - Property and decorator
- Python course
- Intermediate
- Lesson 41/116
- 5 min
Combine decorators and @property to write a validated attribute.
Summary - Property and decorator
In this group we covered decorator basics, function decorators, @property with @x.setter, caching with @cached_property and metadata protection with @functools.wraps.
A decorator is written as @name and wraps the target function. @property intercepts reads, @x.setter writes. @cached_property computes once; @functools.wraps keeps the target's name and docstring. Now we'll write an example that combines these.
Practice Combined summary example
Start with from functools import cached_property. Define a Square class; def __init__(self, side): and in the body write self.side = side. Add a method def perimeter(self): with @property; body return 4 * self.side. Add a method def area(self): with @cached_property; body return self.side ** 2. After the class create s = Square(5) and print with print(s.perimeter, s.area).
Starter code
# Write the Square class with @property and @cached_propertySample solution
# Write the Square class with @property and @cached_property
from functools import cached_property
class Square:
def __init__(self, side):
self.side = side
@property
def perimeter(self):
return 4 * self.side
@cached_property
def area(self):
return self.side ** 2
s = Square(5)
print(s.perimeter, s.area)Expected output
20 25
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Which combination is wrong?
- @property + @name.setter + @name.deleter
- @property + @name.getter a second time
- @functools.wraps inside a decorator
- @cached_property alone Correct answer
Explanation: @cached_property already caches reads; no setter is added to it.
2 Match the decorator and its purpose
| Term | Meaning |
|---|---|
@property |
Intercepts reads |
@cached_property |
Caching |
@functools.wraps |
Preserves metadata |
@name.setter |
Intercepts writes |
3 Import cached_property and ...
from functools import cached_property, ____
def call(fn):
@functools.wraps(fn)
def wrapper(*a, **k):
return fn(*a, **k)
return wrapper
from functools import cached_property, wraps
def call(fn):
@functools.wraps(fn)
def wrapper(*a, **k):
return fn(*a, **k)
return wrapper
Explanation: wraps is also imported from the functools module.
4 Match the class parts
| Term | Meaning |
|---|---|
__init__ |
Instance setup |
@property |
Read attribute |
@cached_property |
Cached computation |
self.side |
Instance attribute |