LevelJar Sign in

Python course / Advanced

Decorators

Read the @ line for what it is, and write decorators that wrap, configure and register functions. A wrapper without functools.wraps quietly throws away the name, docstring and signature of what it wrapped.

  • closures
  • wrapping
  • functools.wraps
  • keeping state
  • arguments
  • stacking
  • methods
  • registries

Start this module

Runs in your browser. Start straight away; create an account when you want your progress kept.

a decorator that counts calls
import functools


def counted(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        wrapper.calls += 1
        return func(*args, **kwargs)

    wrapper.calls = 0
    return wrapper


@counted
def area(width, height):
    """Area of a rectangle."""
    return width * height


area(3, 4)
area(5, 6)
print("calls:", area.calls)
print("name:", area.__name__)
print("doc:", area.__doc__)
calls: 2
name: area
doc: Area of a rectangle.

What you will learn

The lessons in this module

  • What the @ line does
  • A decorator is a function that makes a function
  • What a wrapper must pass through
  • functools.wraps
  • Decorators that keep state
  • Decorators that take arguments
  • Functions made in a loop, again
  • Stacking decorators
  • Decorating methods
  • Registering with decorators
  • Decorating classes
  • A timing decorator
  • A cache by hand, and functools' own
  • Checking hints at runtime
  • property, taken apart
  • When a decorator is the wrong tool
  • Capstone: one rule, every method
  • Module review: the stall's command line

Ready when you are

Start this module

Previous: Iterators and generators. Next: Context managers. All modules are on the course page.