python-asyncio TypeError:object dict不能在'await'表达式中使用

Ril*_*hes 13 python python-asyncio

我正在使用第三方模块从API检索数据.我只是想异步等待模块返回有时需要几秒钟的数据并冻结我的应用程序.但是,当我尝试等待对该模块的调用时,我收到TypeError:

TypeError: object dict can't be used in 'await' expression

import thirdPartyAPIwrapper

async def getData():
    retrienveData = await thirdPartyAPIWrapper.data()
    return await retrieveData

def main():
    loop = asncio.get_event_loop()
    data = loop.run_until_complete(getData())
    loop.close
    return data
Run Code Online (Sandbox Code Playgroud)

为什么我不等待类型('dict')?有没有解决的办法?如果与asyncio的异步/等待不能与不返回协程的第三方模块一起工作那么我的其他选择是什么?

Mik*_*mov 19

只能async def等待异步(定义)函数.整个想法是,这些函数是以特殊的方式编写的,await它们可以在不阻塞事件循环的情况下运行它们.

如果你想从普通(定义的def)函数获得需要花费相当长时间才能执行的结果,你可以选择以下选项:

  • 将整个函数重写为异步
  • 在另一个线程中调用此函数并等待异步结果
  • 在另一个进程中调用此函数并等待异步结果

通常你想选择第二个选项.

以下是如何执行此操作的示例:

import asyncio
import time
from concurrent.futures import ThreadPoolExecutor


_executor = ThreadPoolExecutor(1)


def sync_blocking():
    time.sleep(2)


async def hello_world():
    # run blocking function in another thread,
    # and wait for it's result:
    await loop.run_in_executor(_executor, sync_blocking)


loop = asyncio.get_event_loop()
loop.run_until_complete(hello_world())
loop.close()
Run Code Online (Sandbox Code Playgroud)

请阅读有关asyncio如何工作的答案.我认为它会对你有所帮助.

  • 请注意,与 Javascript 不同的是,Python 在创建时并没有考虑到异步性。在 Python 中,如果你做一些异步的事情,你需要明确地做:明确地定义异步函数。通用函数不能不努力就变成异步的。这就是为什么您需要线程来异步运行同步函数的原因。 (4认同)

MD *_*YON 9

您不需要等待哪个函数正在异步运行

async def getData():
    retrienveData = thirdPartyAPIWrapper.data()
    return retrieveData
Run Code Online (Sandbox Code Playgroud)


Ser*_*rge 5

作为thirdPartyAPIWrapper.data()一个普通的同步函数,你应该在另一个线程中调用它。

库中有一个辅助函数asgiref
假设我们有一个带参数的阻塞函数:

import asyncio
import time

from asgiref.sync import sync_to_async


def blocking_function(seconds: int) -> str:
    time.sleep(seconds)
    return f"Finished in {seconds} seconds"

async def main():
    seconds_to_sleep = 5
    function_message = await sync_to_async(blocking_function)(seconds_to_sleep)
    print(function_message)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
Run Code Online (Sandbox Code Playgroud)

async_to_sync该库中还有一个辅助函数。