【问题标题】:Automatic conversion of standard function into asynchronous function in PythonPython中标准函数自动转换为异步函数
【发布时间】:2022-01-27 22:47:38
【问题描述】:

在我写的大部分异步协程中,只需要替换函数定义def func() -> async def func() 和sleep time.sleep(s) -> await asyncio.sleep(s)即可。

是否可以将标准python函数转换为异步函数,其中所有time.sleep(s)都转换为await asyncio.sleep(s)

示例

任务期间的表现
在任务期间衡量绩效

import asyncio
import random

async def performance_during_task(task):
    stop_event = asyncio.Event()

    target_task = asyncio.create_task(task(stop_event))
    perf_task = asyncio.create_task(measure_performance(stop_event))

    await target_task
    await perf_task

async def measure_performance(event):
    while not event.is_set():
        print('Performance: ', random.random())
        await asyncio.sleep(.2)

if __name__ == "__main__":
    asyncio.run(
        performance_during_task(task)
    )

任务
任务必须用async defawait asyncio.sleep(s) 定义

async def task(event):
    for i in range(10):
        print('Step: ', i)
        await asyncio.sleep(.2)
    
    event.set()

进入->

简单的任务定义
为了让其他人不用担心异步等。我希望他们能够正常定义任务(例如使用装饰器?)

@as_async
def easy_task(event):
    for i in range(10):
        print('Step: ', i)
        time.sleep(.2)
    
    event.set()

这样它就可以用作异步函数,例如performance_during_task()

【问题讨论】:

  • This 可能值得探索

标签: python asynchronous python-asyncio python-decorators


【解决方案1】:

我想我找到了一个类似于 cmets 中提到的有趣 GitHub 示例和类似帖子 here 的解决方案。

我们可以写一个装饰器喜欢

from functools import wraps, partial


def to_async(func):
    @wraps(func)  # Makes sure that function is returned for e.g. func.__name__ etc.
    async def run(*args, loop=None, executor=None, **kwargs):
        if loop is None:
            loop = asyncio.get_event_loop(). # Make event loop of nothing exists
        pfunc = partial(func, *args, **kwargs)  # Return function with variables (event) filled in
        return await loop.run_in_executor(executor, pfunc).
    return run

这样简单的任务就变成了

@to_async
def easy_task(event):
    for i in range(10):
        print('Step: ', i)
        time.sleep(.2)
    
    event.set()

wraps 确保我们可以调用原始函数的属性 (explained here)。

部分按照here的解释填写变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    相关资源
    最近更新 更多