Python中的同步与异步装饰器实现详解

107 阅读5分钟

更多学习内容:ipengtao.com

在Python中,装饰器是一种强大的工具,它可以用来修改、扩展或包装函数或方法的行为。在本文中,将探讨如何使用装饰器来实现同步和异步的功能,以及如何在不同的情况下选择合适的装饰器。

什么是装饰器?

装饰器是一种特殊的函数,它可以接受一个函数或方法作为参数,并返回一个新的函数或方法,通常用于修改被装饰函数的行为或添加额外的功能。装饰器在Python中被广泛应用于日志记录、性能分析、权限检查等场景。

装饰器的基本结构如下:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 在调用原始函数之前可以执行一些操作
        result = func(*args, **kwargs)
        # 在调用原始函数之后可以执行一些操作
        return result
    return wrapper

@decorator
def my_function():
    # 原始函数的实现
    pass

在上面的示例中,decorator 是一个装饰器函数,它接受一个函数 func 作为参数,并返回一个新的函数 wrapper。通过在函数定义前使用 @decorator 注解,可以将 my_function 装饰为 wrapper 函数的调用。

同步装饰器的实现

同步装饰器用于修饰同步函数或方法,不涉及异步操作。

基本的同步装饰器

首先,创建一个基本的同步装饰器,用于测量函数的执行时间:

import time

def timing_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

@timing_decorator
def slow_function():
    time.sleep(2)
    print("慢函数执行完成")

@timing_decorator
def fast_function():
    print("快函数执行完成")

slow_function()
fast_function()

运行上述代码,将看到如下输出:

慢函数执行完成
slow_function 执行时间: 2.0003552436828613 秒
快函数执行完成
fast_function 执行时间: 1.3113021850585938e-05 秒

在这个例子中,timing_decorator 装饰器测量了被装饰函数的执行时间,并在执行完成后打印出来。通过使用装饰器,可以在不修改原始函数代码的情况下添加这个功能。

带参数的同步装饰器

有时,需要在装饰器中传递参数,以便根据不同的配置执行不同的操作。

下面是一个带参数的同步装饰器的示例,它可以指定是否应该打印执行时间:

import time

def timing_decorator(print_time=True):
    def decorator(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            if print_time:
                print(f"{func.__name__} 执行时间: {end_time - start_time} 秒")
            return result
        return wrapper
    return decorator

@timing_decorator(print_time=True)
def slow_function():
    time.sleep(2)
    print("慢函数执行完成")

@timing_decorator(print_time=False)
def fast_function():
    print("快函数执行完成")

slow_function()
fast_function()

运行上述代码,将看到如下输出:

慢函数执行完成
slow_function 执行时间: 2.000269889831543 秒
快函数执行完成

在这个例子中,timing_decorator 装饰器接受一个 print_time 参数,用于控制是否打印执行时间。通过传递不同的参数值,可以定制装饰器的行为。

异步装饰器的实现

异步装饰器用于修饰异步函数或方法,涉及到 asyncawait 关键字。

基本的异步装饰器

首先,创建一个基本的异步装饰器,用于测量异步函数的执行时间:

import asyncio

def async_timing_decorator(func):
    async def wrapper(*args, **kwargs):
        start_time = time.time()
        result = await func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间: {end_time - start_time} 秒")
        return result
    return wrapper

@async_timing_decorator
async def slow_async_function():
    await asyncio.sleep(2)
    print("慢异步函数执行完成")

@async_timing_decorator
async def fast_async_function():
    print("快异步函数执行完成")

asyncio.run(slow_async_function())
asyncio.run(fast_async_function())

运行上述代码,将看到如下输出:

慢异步函数执行完成
slow_async_function 执行时间: 2.00056791305542 秒
快异步函数执行完成
fast_async_function 执行时间: 0.0002598762512207031 秒

在这个例子中,async_timing_decorator 装饰器用于测量异步函数的执行时间,并在执行完成后打印出来。注意,在异步函数定义前,使用了 @async_timing_decorator 注解来应用装饰器。

带参数的异步装饰器

与同步装饰器一样,也可以创建带参数的异步装饰器,以便在不同的情况下执行不同的操作。

以下是一个带参数的异步装饰器示例,可以控制是否打印执行时间:

import asyncio

def async_timing_decorator(print_time=True):
    def decorator(func):
        async def wrapper(*args, **kwargs):
            start_time = time.time()
            result = await func(*args, **kwargs)
            end_time = time.time()
            if print_time:
                print(f"{func.__name__} 执行时间: {end_time - start_time} 秒")
            return result
        return wrapper
    return decorator

@async_timing_decorator(print_time=True)
async def slow_async_function():
    await asyncio.sleep(2)
    print("慢异步函数执行完成")

@async_timing_decorator(print_time=False)
async def fast_async_function():
    print("快异步函数执行完成")

asyncio.run(slow_async_function())
asyncio.run(fast_async_function())

运行上述代码,将看到如下输出:

慢异步函数执行完成
slow_async_function 执行时间: 2.0001399517059326 秒
快异步函数执行完成

与同步装饰器一样,带参数的异步装饰器可以根据需要自定义装饰器的行为。

总结

在Python中,装饰器是一种非常强大的工具,用于修改、扩展或包装函数和方法的行为。本文详细讨论了如何实现同步和异步的装饰器,并提供了示例代码以说明其用法。通过使用装饰器,可以轻松地添加各种功能,同时保持代码的清晰和可维护性。希望本文对大家理解Python中的装饰器以及如何实现同步和异步装饰器有所帮助。


Python学习路线

更多学习内容:ipengtao.com

Python基础知识.png