5.7. Decorator Stdlib Functools¶
5.7.1. Wraps¶
from functools import wraps
@wraps(func)
def mydecorator(func):
def wrapper(*args, **kwargs):
"""wrapper docstring"""
return func(*args, **kwargs)
return wrapper
@mydecorator
def myfunction(x):
"""myfunction docstring"""
print(x)
print(myfunction.__name__)
# wrapper
print(myfunction.__doc__)
# wrapper docstring
from functools import wraps
def mydecorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""wrapper docstring"""
return func(*args, **kwargs)
return wrapper
@mydecorator
def myfunction(x):
"""myfunction docstring"""
print(x)
print(myfunction.__name__)
# myfunction
print(myfunction.__doc__)
# myfunction docstring
5.7.2. Cached Property¶
from functools import cached_property
@cached_property(func)
import statistics
from functools import cached_property
class Iris:
def __init__(self, *args):
self._measurements = args
@cached_property
def mean(self):
return statistics.mean(self._measurements)
@cached_property
def stdev(self):
return statistics.stdev(self._measurements)
flower = Iris(5.1, 3.5, 1.4, 0.2)
flower.stdev()
flower.mean()
5.7.3. LRU (least recently used) cache¶
from functools import lru_cache
@lru_cache(maxsize=None)
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
[fib(n) for n in range(16)]
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]
fib.cache_info()
# CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)
5.7.4. Assignments¶
"""
* Assignment: Decorator Functools Func
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min
English:
1. Use code from "Given" section (see below)
2. Use `functools.wraps` in correct place
3. Run doctests - all must succeed
Polish:
1. Użyj kodu z sekcji "Given" (patrz poniżej)
2. Użyj `functools.wraps` w odpowiednim miejscu
3. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> @mydecorator
... def hello():
... '''Hello Docstring'''
>>> hello.__name__
'hello'
>>> hello.__doc__
'Hello Docstring'
"""
# Given
from functools import wraps
def mydecorator(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
"""
* Assignment: Decorator Functools Args
* Complexity: easy
* Lines of code: 1 lines
* Time: 2 min
English:
1. Use code from "Given" section (see below)
2. Use `functools.wraps` in correct place
3. Run doctests - all must succeed
Polish:
1. Użyj kodu z sekcji "Given" (patrz poniżej)
2. Użyj `functools.wraps` w odpowiednim miejscu
3. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> @mydecorator(happy=False)
... def hello():
... '''Hello Docstring'''
>>> hello.__name__
'hello'
>>> hello.__doc__
'Hello Docstring'
"""
# Given
from functools import wraps
def mydecorator(happy=True):
def decorator(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorator
"""
* Assignment: Decorator Functools Cls
* Complexity: easy
* Lines of code: 2 lines
* Time: 5 min
English:
1. Use code from "Given" section (see below)
2. Modify code to restore docstring and name from decorated class
3. Run doctests - all must succeed
Polish:
1. Użyj kodu z sekcji "Given" (patrz poniżej)
2. Zmodyfikuj kod aby przywrócić docstring oraz nazwę z dekorowanej klasy
3. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> @mydecorator
... class Hello:
... '''Hello Docstring'''
>>> hello = Hello()
>>> hello.__name__
'Hello'
>>> hello.__doc__
'Hello Docstring'
"""
# Given
def mydecorator(cls):
class Wrapper(cls):
pass
return Wrapper