Python中的装饰器原理与应用
字数 848 2025-11-02 08:11:07

Python中的装饰器原理与应用

题目描述
装饰器(Decorator)是Python中一种高级语法特性,它允许在不修改原函数代码的情况下,为函数或类添加额外的功能(如日志记录、权限校验、性能监控等)。请解释装饰器的工作原理,并举例说明其具体应用场景。


1. 装饰器的基本概念

装饰器的本质是一个高阶函数,它接收一个函数作为参数,并返回一个新的函数(或可调用对象)。其核心思想是函数是第一类对象,即函数可以被赋值、传递或作为返回值。

关键点

  • Python中函数可以嵌套定义(闭包),内部函数可以访问外部函数的变量。
  • 通过@decorator_name语法糖,将装饰器应用到目标函数上。

2. 装饰器的实现步骤

步骤1:定义一个简单的装饰器

以下是一个统计函数执行时间的装饰器示例:

import time

def timer_decorator(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:.2f}秒")
        return result  # 返回原函数的执行结果
    return wrapper  # 返回新函数

# 使用装饰器
@timer_decorator
def example_function(n):
    time.sleep(n)
    return "完成"

# 调用函数
example_function(2)

运行结果

example_function 执行耗时: 2.00秒

步骤2:理解装饰器语法糖的作用

@timer_decorator 等价于以下代码:

def example_function(n):
    time.sleep(n)
    return "完成"

example_function = timer_decorator(example_function)  # 手动替换原函数

3. 装饰器的进阶用法

(1)带参数的装饰器

若装饰器本身需要参数(如设置日志级别),需再嵌套一层函数:

def repeat(n):  # 外层函数接收装饰器参数
    def decorator(func):  # 中层接收被装饰函数
        def wrapper(*args, **kwargs):
            for i in range(n):
                result = func(*args, **kwargs)
                print(f"第{i+1}次执行结果: {result}")
            return result
        return wrapper
    return decorator

@repeat(3)  # 重复执行3次
def greet(name):
    return f"Hello, {name}"

greet("Alice")

输出

第1次执行结果: Hello, Alice  
第2次执行结果: Hello, Alice  
第3次执行结果: Hello, Alice  

(2)保留原函数的元信息

装饰器会覆盖原函数的__name____doc__等属性,需使用functools.wraps修复:

from functools import wraps

def timer_decorator(func):
    @wraps(func)  # 保留原函数的元信息
    def wrapper(*args, **kwargs):
        # ... 同上
        return result
    return wrapper

(3)类装饰器

通过实现__call__方法,类也可以作为装饰器:

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.call_count = 0

    def __call__(self, *args, **kwargs):
        self.call_count += 1
        print(f"函数已被调用 {self.call_count} 次")
        return self.func(*args, **kwargs)

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

say_hello()  # 输出:函数已被调用 1 次  
say_hello()  # 输出:函数已被调用 2 次  

4. 装饰器的应用场景

  1. 日志记录:自动记录函数调用参数和返回值。
  2. 权限校验:检查用户权限后再执行函数(如Web框架中的@login_required)。
  3. 缓存:缓存函数结果以避免重复计算(如functools.lru_cache)。
  4. 性能测试:统计函数执行时间(如示例中的timer_decorator)。

5. 总结

  • 装饰器基于闭包和函数式编程实现,是Python的元编程特性之一。
  • 通过@语法糖简化调用,但本质是函数替换。
  • 注意装饰器嵌套时的执行顺序(从下往上)。
  • 实际开发中应使用functools.wraps保留原函数信息。
Python中的装饰器原理与应用 题目描述 装饰器(Decorator)是Python中一种高级语法特性,它允许在不修改原函数代码的情况下,为函数或类添加额外的功能(如日志记录、权限校验、性能监控等)。请解释装饰器的工作原理,并举例说明其具体应用场景。 1. 装饰器的基本概念 装饰器的本质是一个 高阶函数 ,它接收一个函数作为参数,并返回一个新的函数(或可调用对象)。其核心思想是 函数是第一类对象 ,即函数可以被赋值、传递或作为返回值。 关键点 : Python中函数可以嵌套定义(闭包),内部函数可以访问外部函数的变量。 通过 @decorator_name 语法糖,将装饰器应用到目标函数上。 2. 装饰器的实现步骤 步骤1:定义一个简单的装饰器 以下是一个统计函数执行时间的装饰器示例: 运行结果 : 步骤2:理解装饰器语法糖的作用 @timer_decorator 等价于以下代码: 3. 装饰器的进阶用法 (1)带参数的装饰器 若装饰器本身需要参数(如设置日志级别),需再嵌套一层函数: 输出 : (2)保留原函数的元信息 装饰器会覆盖原函数的 __name__ 、 __doc__ 等属性,需使用 functools.wraps 修复: (3)类装饰器 通过实现 __call__ 方法,类也可以作为装饰器: 4. 装饰器的应用场景 日志记录 :自动记录函数调用参数和返回值。 权限校验 :检查用户权限后再执行函数(如Web框架中的 @login_required )。 缓存 :缓存函数结果以避免重复计算(如 functools.lru_cache )。 性能测试 :统计函数执行时间(如示例中的 timer_decorator )。 5. 总结 装饰器基于闭包和函数式编程实现,是Python的 元编程 特性之一。 通过 @ 语法糖简化调用,但本质是函数替换。 注意装饰器嵌套时的执行顺序(从下往上)。 实际开发中应使用 functools.wraps 保留原函数信息。