Fundamentals 9 min read

Understanding Python Decorators: Concepts, Implementations, and Practical Applications

This article provides a comprehensive guide to Python decorators, covering their basic concept, step‑by‑step implementations of simple, parameterized, class‑based, and utility decorators, practical use‑cases such as logging, timing, permission checks, and how to preserve metadata with functools.wraps.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Understanding Python Decorators: Concepts, Implementations, and Practical Applications

Decorators are a powerful feature in Python that allow additional functionality to be added to a function dynamically without modifying the original function.

Table of Contents

Basic concept of decorators

Implementation of a simple decorator

Parameterized decorators

Real‑world application scenarios

Class decorators

Using functools.wraps to preserve function metadata

Summary

1. Basic Concept of Decorators

A decorator is essentially a function that takes another function as an argument and returns a new function. Its purpose is to add extra behavior to the original function without changing its code.

2. Simple Decorator Implementation

Example 1: Basic Decorator

Use case: Add logging before and after a function call.

def my_decorator(func):
    def wrapper():
        print("函数调用前执行")
        func()  # call original function
        print("函数调用后执行")
    return wrapper

@my_decorator

def say_hello():
    print("Hello, World!")

say_hello()

Output:

函数调用前执行
Hello, World!
函数调用后执行

Explanation: my_decorator is the decorator, wrapper is the inner function that adds extra logic before and after calling the original function.

3. Parameterized Decorator

Example 2: Decorator Supporting Arguments

Use case: The decorator needs to support functions that accept parameters.

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("函数调用前执行")
        result = func(*args, **kwargs)
        print("函数调用后执行")
        return result
    return wrapper

@my_decorator

def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Output:

函数调用前执行
Hello, Alice!
函数调用后执行

Explanation: By using *args and **kwargs , the decorator can handle functions with arbitrary arguments.

4. Real‑World Application Scenarios

Example 3: Measuring Function Execution Time

Use case: Measure how long a function takes to run.

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:.4f} 秒")
        return result
    return wrapper

@timer

def slow_function():
    time.sleep(2)
    print("慢函数执行完成")

slow_function()

Output:

慢函数执行完成
函数 slow_function 执行耗时 2.0002 秒

Explanation: The timer decorator uses the time module to record execution duration.

Example 4: Logging Calls

Use case: Record function call information.

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"调用函数:{func.__name__},参数:{args}{kwargs}")
        result = func(*args, **kwargs)
        print(f"函数 {func.__name__} 执行完成,返回结果:{result}")
        return result
    return wrapper

@log_decorator

def add(a, b):
    return a + b

print(add(5, 3))

Output:

调用函数:add,参数:(5, 3) {}
函数 add 执行完成,返回结果:8
8

Explanation: log_decorator records the function name, its arguments, and the return value.

Example 5: Permission Verification

Use case: Verify user permissions before executing a function.

def login_required(func):
    def wrapper(*args, **kwargs):
        if not is_logged_in():
            print("请先登录")
            return None
        return func(*args, **kwargs)
    return wrapper

@login_required

def sensitive_operation():
    print("执行敏感操作")

def is_logged_in():
    return False  # simulate not logged in

sensitive_operation()

Output:

请先登录

Explanation: login_required checks login status before allowing the original function to run.

Example 6: Repeating Function Execution

Use case: Execute a function multiple times.

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

@repeat(3)

def say_hello():
    print("Hello!")

say_hello()

Output:

Hello!
Hello!
Hello!

Explanation: The repeat decorator uses a nested function to call the target function n times.

5. Class Decorator

Example 7: Class‑Based Decorator

Use case: Implement a decorator using a class.

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0
    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"第 {self.num_calls} 次调用 {self.func.__name__}")
        return self.func(*args, **kwargs)

@CountCalls

def test_function():
    print("执行测试函数")

test_function()
test_function()

Output:

第 1 次调用 test_function
执行测试函数
第 2 次调用 test_function
执行测试函数

Explanation: The class implements __call__ to act as a decorator, tracking how many times the function is invoked.

6. Using functools.wraps to Preserve Function Metadata

Example 8: Preserve Name and Docstring

Use case: Prevent a decorator from overwriting the original function’s name and documentation.

import functools

def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print("函数调用前执行")
        return func(*args, **kwargs)
    return wrapper

@my_decorator

def example_function():
    """这是一个示例函数"""
    print("执行示例函数")

print(example_function.__name__)  # output: example_function
print(example_function.__doc__)   # output: 这是一个示例函数

Explanation: functools.wraps copies the original function’s __name__ and __doc__ attributes to the wrapper.

7. Summary

Decorators are a highly useful feature in Python that enable dynamic addition of functionality to functions without altering their source code. They can be employed for logging, performance monitoring, permission checks, and more complex logic via class‑based implementations. Understanding decorators equips you with a powerful tool for clean and reusable code.

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