Fundamentals 7 min read

Understanding Python Decorators: Theory and 10 Practical Use Cases

This article explains the concept and implementation of Python decorators as higher‑order functions and provides ten practical code examples—including timer, debugger, parameterized, class‑based, caching, permission, logging, exception handling, authentication, and chained decorators—to illustrate their versatile applications.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Understanding Python Decorators: Theory and 10 Practical Use Cases

Python decorators are a powerful metaprogramming tool that can modify, extend, or wrap the behavior of functions and classes. A decorator is essentially a function or class that receives a function or class as input and returns a new callable.

In Python, a decorator is applied to the target using the @decorator_name syntax placed before the function or class definition.

The implementation principle of decorators is that they are higher‑order functions: they accept a function as a parameter and return a new function (the wrapper). This allows additional operations to be performed before and after the original function call without modifying its source code.

The general implementation pattern is shown below:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 在调用原始函数之前的操作
        ...
        result = func(*args, **kwargs)  # 调用原始函数
        # 在调用原始函数之后的操作
        ...
        return result
    return wrapper

Ten practical decorator scenarios are presented, each with a brief description and full code.

1. Timer decorator – measures the execution time of a function.

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"函数 {func.__name__} 执行时间:{end_time - start_time} 秒")
        return result
    return wrapper

@timer
def my_function():
    # 执行某些操作
    ...

2. Debugger decorator – prints function inputs and outputs for debugging.

def debugger(func):
    def wrapper(*args, **kwargs):
        print(f"调用函数 {func.__name__},输入:{args},{kwargs}")
        result = func(*args, **kwargs)
        print(f"函数 {func.__name__} 的输出:{result}")
        return result
    return wrapper

@debugger
def my_function(x, y):
    # 执行某些操作
    return result

3. Parameterized decorator – allows custom behavior by accepting arguments.

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def my_function():
    # 执行某些操作
    ...

4. Class decorator – uses a class to wrap a function or class.

class Decorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        # 在调用原始函数之前的操作
        ...
        result = self.func(*args, **kwargs)  # 调用原始函数
        # 在调用原始函数之后的操作
        ...
        return result

@Decorator
def my_function():
    # 执行某些操作
    ...

5. Cache decorator – caches function results to avoid redundant computation.

def cache(func):
    cached_results = {}

    def wrapper(*args, **kwargs):
        key = (args, tuple(sorted(kwargs.items())))
        if key not in cached_results:
            cached_results[key] = func(*args, **kwargs)
        return cached_results[key]
    return wrapper

@cache
def my_function(x, y):
    # 执行某些操作
    return result

6. Permission‑check decorator – verifies user permissions before allowing function execution.

def check_permission(func):
    def wrapper(*args, **kwargs):
        if check_user_permission():
            return func(*args, **kwargs)
        else:
            raise PermissionError("用户没有访问权限")
    return wrapper

@check_permission
def my_function():
    # 执行某些操作
    ...

7. Logging decorator – records function calls and results.

def log(func):
    def wrapper(*args, **kwargs):
        logging.info(f"调用函数 {func.__name__},输入:{args},{kwargs}")
        result = func(*args, **kwargs)
        logging.info(f"函数 {func.__name__} 的输出:{result}")
        return result
    return wrapper

@log
def my_function():
    # 执行某些操作
    ...

8. Exception‑handling decorator – catches and processes exceptions raised by the wrapped function.

def handle_exception(func):
    def wrapper(*args, **kwargs):
        try:
            result = func(*args, **kwargs)
        except Exception as e:
            # 处理异常
            ...
        return result
    return wrapper

@handle_exception
def my_function():
    # 执行某些操作
    ...

9. Authentication decorator – validates user identity before function execution.

def authenticate(func):
    def wrapper(*args, **kwargs):
        if authenticate_user():
            return func(*args, **kwargs)
        else:
            raise AuthenticationError("用户身份验证失败")
    return wrapper

@authenticate
def my_function():
    # 执行某些操作
    ...

10. Chained decorators – demonstrates applying multiple decorators in sequence.

@decorator1
@decorator2
@decorator3
def my_function():
    # 执行某些操作
    ...

Overall, decorators are a versatile and flexible metaprogramming mechanism in Python that enhance code reusability and maintainability by allowing developers to modify, extend, and wrap functions and classes without altering their original implementations.

metaprogrammingprogrammingdecoratorcode
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.