背景
我們在Python非同步程式編寫中經常要用到如下的結構
import asyncio
async def doAsync():
await asyncio.sleep(0)
#...
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(doAsync())
loop.close()
這當然是很不錯的,但當你第二次使用loop的時候程式就會丟擲異常RuntimeError: Event loop is closed
,這也無可厚非,理想的程式也應該是在一個時間迴圈中解決掉各種非同步IO的問題。
但放在終端環境如Ipython中,如果想要練習Python的非同步程式的編寫的話每次都要重新開啟終端未免太過於麻煩,這時候要探尋有沒有更好的解決方案。
解決方案
我們可以使用asyncio.new_event_loop
函式建立一個新的事件迴圈,並使用asyncio.set_event_loop
設定全域性的事件迴圈,這時候就可以多次執行非同步的事件迴圈了,不過最好儲存預設的asyncio.get_event_loop
並在事件迴圈結束的時候還原回去。
最終我們的程式碼就像這樣。
程式碼
import asyncio
async def doAsync():
await asyncio.sleep(0)
#...
def runEventLoop()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(doAsync())
loop.close()
if __name__ == "__main__":
oldloop = asyncio.get_event_loop()
runEventLoop()
runEventLoop()
asyncio.set_event_loop(oldloop)
感想
事件迴圈本來就是要一起做很多事情,在正式的Python程式碼中還是隻用一個預設的事件迴圈比較好,平時的學習練習的話倒是隨意了。