Python 装饰器:包装和修改函数

学习 Python 装饰器来动态修改函数行为。了解包装器函数、@ 语法以及处理装饰器中的参数。

在编辑器中尝试

概述

装饰器是 Python 最优雅、最强大的设计模式之一。它们允许开发人员修改或扩展函数、方法或类的行为,而无需永久更改其源代码。将装饰器视为将一个函数包装在另一个函数中以执行预处理和后处理步骤。这使得装饰器非常适合实现横切关注点,例如日志记录、计时、验证或访问控制。

从本质上讲,装饰器之所以起作用,是因为 Python 函数是一等公民。这意味着函数可以作为参数传递给其他函数、从函数返回以及分配给变量。装饰器只是一个函数,它接受另一个函数作为参数,定义一个嵌套的包装函数,该函数执行原始函数以及一些额外的逻辑,并返回此包装函数以替换原始函数。

为了使装饰器的应用变得简单和干净,Python 提供了“@decorator_name”语法糖,将其放置在目标函数定义的正上方。当调用修饰函数时,Python 会调用包装器。如果函数接受参数,则包装器必须接受任意参数(“*args”和“**kwargs”)并正确转发它们。了解装饰器使您能够编写高度模块化、干净且 DRY(不要重复自己)的代码。

代码和执行输出

一个自定义装饰器,用于跟踪和记录函数执行细节。

def call_tracker(func):
    """Decorator that tracks and logs function execution details."""
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with args: {args}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} returned: {result}")
        return result
    return wrapper

@call_tracker
def multiply(a, b):
    return a * b

# Calling the decorated function
result = multiply(5, 4)
端子输出
Calling multiply with args: (5, 4)
multiply returned: 20

逐步实施

  • 将运行时指标记录到性能监视器
  • 对路由执行身份验证和授权检查
  • 缓存或记忆昂贵的计算结果

常见问题解答

装饰器如何处理参数?

通过在嵌套包装函数中使用 *args 和 **kwargs,它允许它接收任何位置或关键字参数并将其转发到包装函数。

可以对一个函数应用多个装饰器吗?

是的,您可以堆叠它们。它们将从上到下(从最内层到最外层)的顺序执行。

相关主题

推荐的 Python 资源

通过相关的交互式教程、备忘单和代码比较来扩展您的知识。