Back to all snippets
Library/Python/Decorators
pythonintermediatedecoratorsfunctionspatternsmeta-programming

How to implement Decorators in Python

Extend function behaviour with reusable Python decorators

Quick Answer

A decorator is a function that takes another function and returns a wrapper — annotate with `@decorator_name` to apply it. Always use `@functools.wraps(func)` to preserve the wrapped function's metadata.

Code Snippet

1import functools
2import time
3
4# 1. Timing decorator
5def timer(func):
6    @functools.wraps(func)
7    def wrapper(*args, **kwargs):
8        start = time.perf_counter()
9        result = func(*args, **kwargs)
10        end = time.perf_counter()
11        print(f'{func.__name__} took {end - start:.4f}s')
12        return result
13    return wrapper
14
15# 2. Retry decorator
16def retry(times=3, exceptions=(Exception,)):
17    def decorator(func):
18        @functools.wraps(func)
19        def wrapper(*args, **kwargs):
20            for attempt in range(1, times + 1):
21                try:
22                    return func(*args, **kwargs)
23                except exceptions as e:
24                    if attempt == times:
25                        raise
26                    print(f'Attempt {attempt} failed: {e}. Retrying...')
27        return wrapper
28    return decorator
29
30# Usage
31@timer
32def slow_function():
33    time.sleep(0.5)
34    return 'done'
35
36@retry(times=3, exceptions=(ConnectionError,))
37def fetch_data(url: str):
38    # your HTTP request here
39    pass

What is Decorators?

A Python decorator is a higher-order function that wraps another function to extend its behaviour without modifying its source code. Decorators are used everywhere in Python — from Flask route registration to Django permissions. Understanding how to write your own decorators unlocks a powerful pattern for cross-cutting concerns like logging, timing, and retrying.

How It Works

  1. 1`@decorator` is syntactic sugar for `func = decorator(func)`.
  2. 2The inner `wrapper` function calls the original `func` and can run code before and after.
  3. 3`@functools.wraps(func)` copies `__name__`, `__doc__`, and other metadata to the wrapper.
  4. 4Parametrised decorators add an outer factory function that accepts the parameters and returns the actual decorator.

Common Use Cases

  • Performance timing - Measure how long functions take to run
  • Logging - Automatically log function calls and arguments
  • Retry logic - Retry flaky network requests on failure
  • Access control - Guard functions with authentication checks

Key Benefits

  • Separates cross-cutting concerns from business logic
  • Reusable across many functions without code duplication
  • Compatible with all Python frameworks and libraries
  • Composable — stack multiple decorators on one function

Common Mistakes to Avoid

  • Forgetting `@functools.wraps(func)` — without it, the wrapper replaces the function's `__name__` and `__doc__`, breaking introspection and documentation tools.
  • Calling the decorator instead of passing it — `@timer()` vs `@timer` — only use parentheses for parametrised decorators.
  • Mutating shared state inside the wrapper — the wrapper is called every time the function is called, so be careful with closures over mutable objects.

Quick Tips

  • Click the "Copy" button above to copy the code to your clipboard
  • This code is production-ready and can be used in your projects immediately
  • Check out related snippets below for more python examples

Frequently Asked Questions

Can I stack multiple decorators on one function?

Yes. Decorators are applied bottom-up: `@a @b def f()` is equivalent to `f = a(b(f))`. The outermost decorator wraps the already-wrapped function.

About This Python Code Snippet

This free python code snippet for decorators is production-ready and copy-paste friendly. Whether you are building a web app, API, or frontend interface, this intermediate-level example will help you implement decorators quickly and correctly.

All snippets in the Snippetly library follow python best practices and are tested for real-world use. You can adapt this code to work with React, Vue, Node.js, or any project that uses python.

Tags: decorators, functions, patterns, meta-programming  | Language: python  | Difficulty: intermediate  | Category: Python

Build Your Own Snippet Library

Organise your team's code snippets with Snippetly. Share knowledge and boost productivity across your organisation.