MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

22-1-Python高级特性-装饰器(python装饰器详解)

2025-04-05 19:07 huorong 精选文章 4 ℃ 0 评论

1-装饰器

1-1-基本概念

  1. 装饰器本质上是一个高阶函数,是一个可以接受函数作为参数并返回一个新函数的函数。
  2. 它的主要作用是在不改变原函数定义和调用方式的前提下,为原函数增加额外的功能。
  3. 它可以让你在不修改原函数代码的情况下,为函数添加额外的功能。通过使用装饰器,可以提高代码的复用性和可维护性
  4. 应用场景:常见的应用场景包括日志记录、权限验证、性能测试、缓存等。

1-2-语法

Python 使用 `@` 符号来应用装饰器。以下是一个简单的装饰器示例:

1-2-1-代码

# 定义一个装饰器函数
def my_decorator(func):
    def wrapper():
        print("wrapper()......begin......")
        func()
        print("wrapper()......end......")
    return wrapper

# 使用装饰器
@my_decorator
def hello():
    print("Hello!")

# 调用被装饰后的函数
hello()

1-2-2-输出结果

1-2-3-代码分析

  1. 在上述代码中,`my_decorator` 是一个装饰器函数,它接受一个函数 `func` 作为参数,并返回一个新的函数 `wrapper`。
  2. `wrapper` 函数在调用原函数 `func` 的前后分别添加了一些额外的操作。
  3. 使用 `@my_decorator` 语法糖,将 `hello` 函数传递给 `my_decorator` 进行装饰,这样调用 `hello` 函数时,实际上调用的是 `wrapper` 函数。

1-3-带参数的函数使用装饰器

如果原函数带有参数,装饰器中的 `wrapper` 函数也需要接受相应的参数,并将这些参数传递给原函数。示例如下:

1-3-1-代码

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("wrapper()......begin......")
        result = func(*args, **kwargs)
        print("wrapper()......end......")
        return result
    return wrapper

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

result = add(5, 10)
print(result)

1-3-2-输出结果

1-3-3-代码分析

在这个例子中,`wrapper` 函数使用 `*args` 和 `**kwargs` 来接受任意数量的位置参数和关键字参数,并将它们传递给原函数 `add`。

1-4-带参数的装饰器

装饰器本身也可以接受参数。这需要定义一个返回装饰器函数的高阶函数

1-4-1-代码

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 say_hi():
    print("Hi!")

say_hi()

1-4-2-输出结果

1-4-3-代码分析

  1. 在这个例子中,`repeat` 是一个接受参数 `n` 的高阶函数,它返回一个装饰器函数 `decorator`。
  2. `decorator` 函数接受一个函数 `func` 作为参数,并返回一个新的函数 `wrapper`。
  3. `wrapper` 函数会重复调用原函数 `func` `n` 次。

1-5-应用场景

1-5-1-日志记录装饰器

日志记录在调试和监控程序运行状态时非常重要,使用装饰器可以方便地为多个函数添加日志记录功能。

代码

import logging

def log_decorator(func):
    def wrapper(*args, **kwargs):
        logging.basicConfig(level=logging.INFO)
        logging.info(f"开始执行函数 {func.__name__},参数: args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        logging.info(f"函数 {func.__name__} 执行完毕,结果: {result}")
        return result
    return wrapper

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

result = add(3, 5)

输出结果

代码分析

  1. `log_decorator` 是一个装饰器函数,它接受一个函数 `func` 作为参数。
  2. `wrapper` 函数在调用原函数 `func` 前后分别记录了函数的执行信息,包括开始执行、传入的参数以及执行结果。
  3. `@log_decorator` 语法糖将 `add` 函数传递给 `log_decorator` 进行装饰,这样调用 `add` 函数时就会自动记录日志。

1-5-2-性能测试装饰器

在优化代码性能时,需要了解函数的执行时间,使用装饰器可以轻松实现函数执行时间的测量。

代码

import time

def performance_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} 秒")
        return result
    return wrapper

@performance_decorator
def slow_function():
    time.sleep(2)

slow_function()

输出结果

代码分析

  1. `performance_decorator` 装饰器在调用原函数前后分别记录了时间,通过计算时间差得到函数的执行时间,并将其打印输出。
  2. 对 `slow_function` 函数应用该装饰器后,每次调用该函数都会显示其执行时间。

1-5-3-权限验证装饰器

在 Web 应用或其他需要权限控制的场景中,可使用装饰器来验证用户是否具有执行某个函数的权限。

代码

def permission_required(permission):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 这里简单模拟权限验证,实际应用中需要根据具体情况实现
            if permission == "admin":
                print("权限验证通过")
                return func(*args, **kwargs)
            else:
                print("权限不足,无法执行该操作")
        return wrapper
    return decorator

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

sensitive_operation()


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

sensitive_operation()

输出结果

代码分析

  1. `permission_required` 是一个带参数的装饰器,它接受一个权限参数 `permission`,并返回一个装饰器函数 `decorator`。
  2. `decorator` 函数接受原函数 `func` 作为参数,`wrapper` 函数在调用原函数之前进行权限验证。如果权限验证通过,则调用原函数;否则,输出权限不足的提示信息。
  3. `@permission_required("admin")` 为 `sensitive_operation` 函数添加了权限验证功能,只有具有 “admin” 权限的用户才能执行该函数。

1-5-4-缓存装饰器

在处理一些计算量较大且结果不经常变化的函数时,使用缓存装饰器可以避免重复计算,提高程序的运行效率。

代码

def cache_decorator(func):
    cache = {}
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrapper

@cache_decorator
def factorial(n):
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))
print(factorial(5))  # 第二次调用时直接从缓存中获取结果

输出结果

代码分析

  1. `cache_decorator` 装饰器使用一个字典 `cache` 来存储函数的输入参数和对应的计算结果。
  2. `wrapper` 函数在调用原函数之前,先检查输入参数是否已经存在于缓存中。如果存在,则直接返回缓存中的结果;否则,调用原函数进行计算,并将结果存入缓存。
  3. 对 `factorial` 函数应用该装饰器后,当多次调用相同参数的 `factorial` 函数时,只有第一次会进行实际计算,后续调用会直接从缓存中获取结果。

Tags:wrapper or

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言