Real Python Cheat Sheet

Download as pdf or txt
Download as pdf or txt
You are on page 1of 3

Real Python Cheat Sheet

realpython.com

Python Decorators Examples


Learn more about decorators in Python in our in-depth tutorial at realpython.com/primer-on-python-decorators/

Using decorators Decorator not changing the decorated function

The normal way of using a decorator is by specifying it just before the definition of If you don’t want to change the decorated function, a decorator is simply a func-
the function you want to decorate: tion taking in and returning a function:

@decorator def name(func):


def f(arg_1, arg_2): # Do something with func
... return func

If you want to decorate an already existing function you can use the following syn- Example: Register a list of decorated functions.
tax:
def register(func):
f = decorator(f) """Register a function as a plug-in"""
PLUGINS[func.__name__] = func
return func

realpython.com 1
Python Decorators Examples

Basic decorator

Template for basic decorator that can modify the decorated function: Example: A timer decorator that prints the runtime of a function.

import functools import functools


import time
def name(func):
@functools.wraps(func) def timer(func):
def wrapper_name(*args, **kwargs): """Print the runtime of the function"""
# Do something before @functools.wraps(func)
value = func(*args, **kwargs) def wrapper_timer(*args, **kwargs):
# Do something after start_time = time.perf_counter()
return value value = func(*args, **kwargs)
return wrapper_name end_time = time.perf_counter()
run_time = end_time - start_time
print(f"Run time: {run_time:.4f} secs")
return value
return wrapper_timer

Decorator with arguments

If you want your decorator to take arguments, create a decorator factory that can Example: Rate limit your code by sleeping a given amount of seconds before call-
create decorators: ing the function.

import functools import functools


import time
def name(arg_1, ...):
def decorator_name(func): def slow_down(rate):
@functools.wraps(func) """Sleep before calling the function"""
def wrapper_name(*args, **kwargs): def decorator_slow_down(func):
# Do something before using arg_1, ... @functools.wraps(func)
value = func(*args, **kwargs) def wrapper_slow_down(*args, **kwargs):
# Do something after using arg_1, ... time.sleep(rate)
return value return func(*args, **kwargs)
return wrapper_name return wrapper_slow_down
return decorator_name return decorator_slow_down

realpython.com 2
Python Decorators Examples

Decorators that can optionally take arguments

If you want your decorator to be able to be called with or without arguments, you Example: Rate limit your code by sleeping an optionally given amount of seconds
need a dummy argument, _func, that is set automatically if the decorator is called before calling the function.
without arguments:
import functools
import functools import time

def name(_func=None, *, arg_1=val_1, ...): def slow_down(_func=None, *, rate=1):


def decorator_name(func): """Sleep before calling the function"""
@functools.wraps(func) def decorator_slow_down(func):
def wrapper_name(*args, **kwargs): @functools.wraps(func)
# Do something before using arg_1, ... def wrapper_slow_down(*args, **kwargs):
value = func(*args, **kwargs) time.sleep(rate)
# Do something after using arg_1, ... return func(*args, **kwargs)
return value return wrapper_slow_down
return wrapper_name
if _func is None:
if _func is None: return decorator_slow_down
return decorator_name else:
else: return decorator_slow_down(_func)
return decorator_name(_func)

Decorators that keep state

If you need your decorator to maintain state, use a class as a decorator: Example: Count the number of times the decorated function is called.

import functools import functools

class Name: class CountCalls:


def __init__(self, func): def __init__(self, func):
functools.update_wrapper(self, func) functools.update_wrapper(self, func)
self.func = func self.func = func
# Initialize state attributes self.num_calls = 0

def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):


# Update state attributes self.num_calls += 1
return self.func(*args, **kwargs) print(f"Call {self.num_calls}")
return self.func(*args, **kwargs)

realpython.com 3

You might also like