python - 是否可以让装饰器在 asyncio 执行器中运行阻塞函数?

标签 python python-3.x asynchronous decorator python-asyncio

我可能需要帮助更好地表达这个问题。我正在通过 python3.7 和一个类(名为 Worker() )编写一个异步 api 接口(interface)。 Worker我想使用 loop.run_in_executor() 运行一些阻止方法。

我想构建一个装饰器,我可以将其添加到所有非 async 之上。 Worker中的方法,但我不断遇到问题。

我被告知我需要await wraps()在下面的装饰器中:

def run_method_in_executor(func, *, loop=None):
    async def wraps(*args):
        _loop = loop if loop is not None else asyncio.get_event_loop()
        return await _loop.run_in_executor(executor=None, func=func, *args)
    return wraps

返回: RuntimeWarning: coroutine 'run_method_in_executor.<locals>.wraps' was never awaited

我不知道如何正确地 await wraps()因为包含函数和修饰函数不是异步的。不确定这是否是由于误解造成的asyncio ,或误解装饰器。

任何帮助(或帮助澄清)将不胜感激!

最佳答案

这里是 Python 3.6+ 的完整示例,它不使用 3.8 弃用的接口(interface)。返回loop.run_in_executor的值可以有效地将包装函数转换为在线程中执行的awaitable,因此您可以等待它的完成。

#!/usr/bin/env python3

import asyncio
import functools
import time


def run_in_executor(_func):
    @functools.wraps(_func)
    def wrapped(*args, **kwargs):
        loop = asyncio.get_event_loop()
        func = functools.partial(_func, *args, **kwargs)
        return loop.run_in_executor(executor=None, func=func)
    return wrapped


@run_in_executor
def say(text=None):
    """Block, then print."""
    time.sleep(1.0)
    print(f'say {text} at {time.monotonic():.3f}')


async def main():
    print(f'beginning at {time.monotonic():.3f}')
    await asyncio.gather(say('asdf'), say('hjkl'))
    await say(text='foo')
    await say(text='bar')


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
beginning at 3461039.617
say asdf at 3461040.618
say hjkl at 3461040.618
say foo at 3461041.620
say bar at 3461042.621

关于python - 是否可以让装饰器在 asyncio 执行器中运行阻塞函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55052883/

相关文章:

python bot阻止对命令的访问

python - 收到错误 13 : permission denied while trying to save my jupyter notebook

python - Pandas 通过追加创建新列

python - 让 Pynng 和 socket 相互对话

python-3.x - 当函数返回特定类型的对象或 None 时,指定什么类型提示?

python - 在嵌套列表中查找项目

angular - 如何使用 observables 在 angular2 中异步绑定(bind)下拉列表?

mvvm - 在 View 模型上测试RACCommand

c# - 'async' 调用图中的最后一次调用是否需要同步?

python - 如何使用rasterio更改光栅的crs?