常见的 Python 装饰器库

2023-03-30 00:00:00 python 装饰 常见

Python 中有许多常用的装饰器库,下面介绍几个比较常用的装饰器库。

functools.lru_cache
functools.lru_cache 是 Python 3.2 中新增的标准库装饰器,用于实现缓存功能。它可以将函数的输入参数与输出结果的映射保存在一个字典中,当下一次相同的参数调用函数时,直接从字典中获取结果,避免了重复计算,提高了函数的执行效率。例如:

import functools

@functools.lru_cache(maxsize=128)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

print(fib(30))  # 输出 832040

在上面的示例中,使用 @functools.lru_cache(maxsize=128) 装饰了 fib 函数,maxsize 参数指定了最多缓存 128 个结果。第一次调用 fib(30) 时,需要递归计算多次,但结果会被缓存,下次调用 fib(30) 时就可以直接返回结果。

functools.partial
functools.partial 是 Python 2.5 中新增的标准库函数,用于将一个函数的部分参数固定下来,生成一个新的函数。例如:

import functools

def say_hello(name, greeting):
    print(f"{greeting}, {name}!")

say_hello_to_pidan = functools.partial(say_hello, name="pidancode.com")
say_hello_to_pidan("Hello")  # 输出 "Hello, pidancode.com!"
say_hello_to_pidan("Hi")     # 输出 "Hi, pidancode.com!"

在上面的示例中,使用 functools.partial 固定了 say_hello 函数的 name 参数为 "pidancode.com",生成了一个新的函数 say_hello_to_pidan。调用 say_hello_to_pidan("Hello") 等价于调用 say_hello("pidancode.com", "Hello")。

wrapt
wrapt 是一个第三方装饰器库,提供了一些高级的装饰器功能,例如可以装饰类的方法,可以自定义装饰器的参数等。例如:

import wrapt

@wrapt.decorator
def my_decorator(wrapped, instance, args, kwargs):
    print("Before the function is called.")
    result = wrapped(*args, **kwargs)
    print("After the function is called.")
    return result

@my_decorator
def my_function():
    print("Inside the function.")

my_function()  # 输出 "Before the function is called."、"Inside the function."、"After the function is called."

在上面的示例中,使用 @wrapt.decorator 装饰器装饰了 my_decorator 函数,my_decorator 函数可以装饰任意函数,并且可以接收装饰器的参数。装饰器函数中的参数 wrapped 表示被装饰的函数,instance 表示被装饰的方法所属的实例(如果是普通函数则为 None),args 和 kwargs 分别表示被装饰的函数的位置参数和关键字参数。在 my_decorator 中打印了一些信息,然后调用了被装饰的函数 wrapped,最后返回结果。

retrying
retrying 是一个第三方装饰器库,用于实现函数的重试机制。当函数执行出错或返回指定的异常时,retrying 会自动重试函数的执行,直到函数返回正确的结果或达到最大重试次数。例如:

import retrying

@retrying.retry(wait_fixed=1000, stop_max_attempt_number=3)
def get_pidancode():
    response = requests.get("https://pidancode.com")
    response.raise_for_status()
    return response.content

print(get_pidancode())  # 输出 pidancode.com 的 HTML 内容

在上面的示例中,使用 @retrying.retry 装饰了 get_pidancode 函数,wait_fixed=1000 参数表示每次重试之间等待 1 秒,stop_max_attempt_number=3 表示最多重试 3 次。当 requests.get 函数返回错误时,retrying 会自动重试,直到 requests.get 函数返回正确的结果或达到最大重试次数。

以上是几个常用的 Python 装饰器库的介绍和示例,当然还有其他的装饰器库,可以根据具体需求选择合适的库来使用。

相关文章