亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

asyncio.run() 不能從正在運行的事件循環中調用

asyncio.run() 不能從正在運行的事件循環中調用

慕婉清6462132 2021-12-21 15:56:26
我想使用 asyncio 來獲取網頁 html。我在 jupyter notebook 中運行以下代碼:import aiofilesimport aiohttpfrom aiohttp import ClientSessionasync def get_info(url, session):    resp = await session.request(method="GET", url=url)    resp.raise_for_status()    html = await resp.text(encoding='GB18030')    with open('test_asyncio.html', 'w', encoding='utf-8-sig') as f:        f.write(html)    return html    async def main(urls):    async with ClientSession() as session:        tasks = [get_info(url, session) for url in urls]        return await asyncio.gather(*tasks)if __name__ == "__main__":    url = ['http://huanyuntianxiazh.fang.com/house/1010123799/housedetail.htm', 'http://zhaoshangyonghefu010.fang.com/house/1010126863/housedetail.htm']    result = asyncio.run(main(url))然而,它返回 RuntimeError: asyncio.run() cannot be called from a running event loop問題是什么?如何解決?
查看完整描述

2 回答

?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

asyncio.run()文件說:

當另一個異步事件循環在同一線程中運行時,無法調用此函數。

在您的情況下,jupyter(IPython ≥ 7.0)已經在運行事件循環:

您現在可以在 IPython 終端和筆記本中的頂層使用 async/await,它應該——在大多數情況下——“正常工作”。將 IPython 更新到版本 7+,將 IPykernel 更新到版本 5+,然后您就可以參加比賽了。

因此,您無需自己啟動事件循環,而是可以await main(url)直接調用,即使您的代碼位于任何異步函數之外。

Jupyter/IPython

async def main():

    print(1)

    

await main()

蟒蛇 (≥ 3.7)


import asyncio


async def main():

    print(1)

    

asyncio.run(main())

在您的代碼中,將給出:


url = ['url1', 'url2']

result = await main(url)


for text in result:

    pass # text contains your html (text) response

警告

與 IPython 相比,Jupyter 使用循環的方式略有不同。


查看完整回答
反對 回復 2021-12-21
?
躍然一笑

TA貢獻1826條經驗 獲得超6個贊

要添加 tocglacet的答案 - 如果想要檢測循環是否正在運行并自動調整(即main()在現有循環上運行,否則asyncio.run()),這里是一個可能有用的片段:


# async def main():

#     ...


try:

    loop = asyncio.get_running_loop()

except RuntimeError:  # 'RuntimeError: There is no current event loop...'

    loop = None


if loop and loop.is_running():

    print('Async event loop already running. Adding coroutine to the event loop.')

    tsk = loop.create_task(main())

    # ^-- https://docs.python.org/3/library/asyncio-task.html#task-object

    # Optionally, a callback function can be executed when the coroutine completes

    tsk.add_done_callback(

        lambda t: print(f'Task done with result={t.result()}  << return val of main()'))

else:

    print('Starting new event loop')

    asyncio.run(main())


查看完整回答
反對 回復 2021-12-21
  • 2 回答
  • 0 關注
  • 1390 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號