【问题标题】:How do we call a normal function where a coroutine is expected?我们如何在需要协程的地方调用普通函数?
【发布时间】:2016-07-24 23:12:45
【问题描述】:

考虑一个调用另一个协程的协程:

async def foo(bar):
     result = await bar()
     return result

如果bar 是协程,这会很好。 如果bar 是一个正常功能,我需要做什么(即我需要用什么包装对bar 的调用)以便此代码执行正确的操作?

async def 定义一个协程是完全可能的,即使它从不做任何异步操作(即从不使用await)。 但是,问题询问如何在foo 的代码中包装/修改/调用常规函数bar,以便可以等待bar

【问题讨论】:

    标签: python concurrency python-asyncio


    【解决方案1】:

    如果需要,只需使用 asyncio.coroutine 包装您的同步函数:

    if not asyncio.iscoroutinefunction(bar):
        bar = asyncio.coroutine(bar)
    

    由于重新包装协程是安全的,所以实际上不需要协程功能测试:

    async_bar = asyncio.coroutine(sync_or_async_bar)
    

    因此,您的代码可以重写如下:

    async def foo(bar):
         return await asyncio.coroutine(bar)()
    

    【讨论】:

    • 这似乎有效。请注意,有趣的是,asyncio.coroutine(normal_function)() 是一个生成器,而 a_coroutine_function() 是一个协程。
    • 有什么方法可以将返回的生成器对象视为任务对象,例如调用Task.done() 并查看它是否仍在运行?
    • Deprecated since version 3.8, will be removed in version 3.10。文档说改用async def,但是将函数转换为协程的面向未来的方法是什么?
    猜你喜欢
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2011-02-15
    • 2017-04-16
    • 2015-08-01
    • 2020-04-27
    相关资源
    最近更新 更多