授课语音

Python 装饰器(Decorator)知识点

一、装饰器概述

1. 什么是装饰器

装饰器(Decorator)是 Python 中的一种设计模式,它允许在不修改原函数代码的前提下,动态地为函数或方法添加额外的功能。简而言之,装饰器就是用来包装一个函数的函数,可以在函数执行前或执行后增加额外的行为。

装饰器广泛应用于日志记录、权限校验、缓存机制等场景。

2. 装饰器的工作原理

装饰器本质上是一个函数,它接受一个函数作为参数,返回一个新的函数。装饰器通过 @ 符号应用于被装饰的函数。

  • 被装饰的函数:是原始函数。
  • 装饰器函数:是一个高阶函数(接收函数作为参数并返回函数),在其内部可以修改原始函数的行为。
3. 装饰器的特点
  • 高阶函数:装饰器本质上是高阶函数,能够接受函数作为参数并返回一个函数。
  • 函数嵌套:装饰器通常返回一个新的函数,这个新函数包含了修改过的功能。
  • 不修改原函数:装饰器通过包装原函数,动态地改变函数的行为。

二、装饰器的基本用法

1. 创建一个简单的装饰器
# 定义一个简单的装饰器
def simple_decorator(func):
    def wrapper():
        print("Before function execution")  # 在执行函数前做一些操作
        func()  # 执行原始函数
        print("After function execution")  # 在执行函数后做一些操作
    return wrapper

# 被装饰的函数
@simple_decorator
def say_hello():
    print("Hello, World!")

# 调用被装饰的函数
say_hello()

输出

Before function execution
Hello, World!
After function execution

注释

  • simple_decorator 是一个装饰器,它接收一个函数 func 作为参数,并返回一个新的函数 wrapper
  • @simple_decorator 语法会将 say_hello 函数传递给装饰器函数 simple_decorator,并返回修改后的函数 wrapper
  • 调用 say_hello() 时,实际调用的是 wrapper(),它在执行原始 say_hello 函数前后增加了打印信息。

2. 带参数的装饰器
# 带参数的装饰器
def decorator_with_args(func):
    def wrapper(arg):
        print("Function is called with argument:", arg)  # 打印函数参数
        return func(arg)  # 调用原函数并传递参数
    return wrapper

# 被装饰的函数
@decorator_with_args
def greet(name):
    print(f"Hello, {name}!")

# 调用被装饰的函数
greet("Alice")

输出

Function is called with argument: Alice
Hello, Alice!

注释

  • decorator_with_args 是带有参数的装饰器,它将传入的函数 func 修改,使得它能够接受参数。
  • greet 函数接受一个 name 参数,并由装饰器 decorator_with_args 进行包装。

3. 装饰器的返回值
# 装饰器返回值示例
def multiply_decorator(func):
    def wrapper(x, y):
        print("Multiplying the numbers")  # 打印提示信息
        return func(x, y) * 2  # 调用原函数,并将结果乘以 2
    return wrapper

# 被装饰的函数
@multiply_decorator
def add(x, y):
    return x + y

# 调用被装饰的函数
result = add(3, 5)
print(f"Result: {result}")

输出

Multiplying the numbers
Result: 16

注释

  • multiply_decorator 是一个装饰器,它包装了 add 函数,并修改了其返回值。
  • 调用 add(3, 5) 时,实际调用的是 wrapper(3, 5),该函数在返回结果之前将 add 的结果乘以 2。

三、带参数的装饰器

装饰器通常与其他参数配合使用,例如用于装饰带有返回值的函数,或者在装饰器内处理动态参数等。

1. 带参数的装饰器实例
# 带参数的装饰器示例
def repeat_decorator(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):  # 调用 func 函数 times 次
                func(*args, **kwargs)
        return wrapper
    return decorator

# 被装饰的函数
@repeat_decorator(times=3)
def say_hello():
    print("Hello!")

# 调用被装饰的函数
say_hello()

输出

Hello!
Hello!
Hello!

注释

  • repeat_decorator 是一个带参数的装饰器,它允许用户动态指定执行次数 times
  • 装饰器通过参数 times 控制被装饰函数 say_hello 的执行次数。

四、常见应用场景

  1. 日志记录:在函数执行前后自动记录日志信息。
  2. 权限检查:检查用户权限,确保执行某个操作时有足够的权限。
  3. 缓存机制:对函数结果进行缓存,避免重复计算。
  4. 性能测试:用于测试函数的执行时间。
1. 日志记录装饰器
import time

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Executing {func.__name__} with arguments {args} and {kwargs}")
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Execution time: {end_time - start_time:.4f} seconds")
        return result
    return wrapper

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

# 调用被装饰的函数
add(5, 10)

输出

Executing add with arguments (5, 10) and {}
Execution time: 0.0001 seconds

注释

  • log_decorator 是一个用于记录函数执行的装饰器,它记录函数的执行时间及传入的参数。

五、总结

装饰器是 Python 中非常强大且灵活的特性,它提供了简洁、优雅的方式来动态地扩展函数的功能。通过装饰器,用户可以在不修改原始函数代码的情况下,增加功能、修改行为、做权限检查、记录日志等操作。掌握装饰器的用法,有助于提高代码的复用性和可维护性。

去1:1私密咨询

系列课程: