4.9. Standard Library Functools

4.9.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

4.9.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()

4.9.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)

4.9.4. Assignments

4.9.4.1. Decorator Functools Func

  • Assignment name: Decorator Functools Func

  • Last update: 2020-10-01

  • Complexity level: easy

  • Lines of code to write: 2 lines

  • Estimated time of completion: 3 min

  • Solution: solution/decorator_functools_func.py

English
  1. Use code from "Input" section (see below)

  2. Use functools.wraps in correct place

  3. Compare result with "Output" section (see below)

Polish
  1. Użyj kodu z sekcji "Input" (patrz poniżej)

  2. Użyj functools.wraps w odpowiednim miejscu

  3. Porównaj wyniki z sekcją "Output" (patrz poniżej)

def mydecorator(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper


@mydecorator
def hello():
    """Hello Docstring"""
Output
>>> hello.__name__
'hello'
>>> hello.__doc__
'Hello Docstring'

4.9.4.2. Decorator Functools Args

  • Assignment name: Decorator Functools Args

  • Last update: 2020-10-01

  • Complexity level: easy

  • Lines of code to write: 2 lines

  • Estimated time of completion: 3 min

  • Solution: solution/decorator_functools_args.py

English
  1. Use code from "Input" section (see below)

  2. Use functools.wraps in correct place

  3. Compare result with "Output" section (see below)

Polish
  1. Użyj kodu z sekcji "Input" (patrz poniżej)

  2. Użyj functools.wraps w odpowiednim miejscu

  3. Porównaj wyniki z sekcją "Output" (patrz poniżej)

def mydecorator(happy=True):
    def decorator(func):
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        return wrapper
    return decorator


@mydecorator(happy=False)
def hello():
    """Hello Docstring"""
Output
>>> hello.__name__
'hello'
>>> hello.__doc__
'Hello Docstring'

4.9.4.3. Decorator Functools Cls

  • Assignment name: Decorator Functools Cls

  • Last update: 2020-10-01

  • Complexity level: easy

  • Lines of code to write: 2 lines

  • Estimated time of completion: 5 min

  • Solution: solution/decorator_functools_cls.py

English
  1. Use code from "Input" section (see below)

  2. Modify code to restore docstring and name from decorated class

  3. Compare result with "Output" section (see below)

Polish
  1. Użyj kodu z sekcji "Input" (patrz poniżej)

  2. Zmodyfikuj kod aby przywrócić docstring oraz nazwę z dekorowanej klasy

  3. Porównaj wyniki z sekcją "Output" (patrz poniżej)

Input
def mydecorator(cls):
    class Wrapper(cls):
        pass
    return Wrapper


@mydecorator
class Hello:
    """Hello Docstring"""
Output
>>> hello = Hello()
>>> hello.__name__
'Hello'
>>> hello.__doc__
'Hello Docstring'