[英]asyncio.get_event_loop() fails when following asyncio.run()
[英]When to use asyncio.get_running_loop() vs asyncio.get_event_loop()?
我已經看到使用運行阻塞代碼
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, blockingfunc)
和
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, blockingfunc)
我們什么時候應該使用asyncio.get_running_loop()
與asyncio.get_event_loop()
?
asyncio.get_event_loop()
具有asyncio.get_running_loop()
、 asyncio.new_event_loop()
和asyncio.set_event_loop()
的特性。
asyncio.get_event_loop()從 3.10 版開始棄用:
獲取當前事件循環。
如果當前OS線程沒有設置current event loop,OS線程是main,set_event_loop()還沒有被調用,asyncio會創建一個新的event loop並設置為current。
返回當前操作系統線程中正在運行的事件循環。
創建並返回一個新的事件循環 object。
將循環設置為當前操作系統線程的當前事件循環
例如,如果運行以下代碼:
import asyncio
async def test():
while True:
print("Test")
await asyncio.sleep(1)
async def call_test():
loop = asyncio.get_running_loop()
loop.create_task(test())
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(call_test())
loop.run_forever()
每秒打印一次Test
:
Test
Test
Test
...
所以現在,我們可以在 call_test asyncio.get_event_loop()
中將call_test()
asyncio.get_running_loop()
為 asyncio.get_event_loop() 並將loop = asyncio.new_event_loop()
和asyncio.set_event_loop(loop)
替換為asyncio.get_event_loop()
,如下所示:
import asyncio
async def test():
while True:
print("Test")
await asyncio.sleep(1)
async def call_test():
loop = asyncio.get_event_loop() # Here
# loop = asyncio.get_running_loop()
loop.create_task(test())
loop = asyncio.get_event_loop() # Here
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)
loop.create_task(call_test())
loop.run_forever()
然后, Test
仍然每秒打印一次:
Test
Test
Test
...
所以,關於何時使用asyncio.get_event_loop()
或asyncio.get_running_loop()
,你不應該在任何時候使用asyncio.get_event_loop()
因為它自 version 3.10 以來已被棄用。 因此,您應該每次都使用asyncio.get_running_loop()
以及asyncio.new_event_loop()
和asyncio.set_event_loop()
。 但是如果你真的想使用asyncio.get_event_loop()
,用它來減少代碼。
按照官方文檔, get_running_loop
和get_event_loop
都是用來實際獲取一個active loop的,區別在於后者get_event_loop
的行為更復雜,因此get_running_loop
可以廣泛應用於存在loop的應用中毫無疑問。
此外,在文檔中建議使用run
方法來獲取事件循環,例如
async def main():
await asyncio.sleep(1)
print('hello')
asyncio.run(main())
代替:
async def main():
await asyncio.sleep(1)
print('hello')
loop = asyncio.get_event_loop()
task = loop.create_task(main)
loop.run_forever()
請注意, run
方法解決方案在 Jupyter Notebook 中可能會很奇怪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.