更新於 2024/12/16閱讀時間約 6 分鐘

[Python教學] 進階:非同步程式設計

在這篇文章中,我們將深入探討 Python 中的非同步程式設計,特別是使用 asyncio 模組來實現事件循環和協程。這將幫助你理解如何在 I/O 密集型任務中提高效率,並充分利用 Python 的非同步特性。

什麼是非同步程式設計?

非同步程式設計允許程式在等待某些操作(如網路請求或檔案讀寫)完成時,能夠執行其他任務。這種方式特別適合 I/O 密集型的應用,例如網頁爬蟲或伺服器應用。與傳統的同步程式設計相比,非同步程式設計可以顯著提高應用的響應速度和效能。

asyncio 模組介紹

asyncio 是 Python 標準庫的一部分,自 Python 3.4 開始提供支持。它提供了一個事件循環來管理協程的執行,並使用 async 和 await 語法來簡化非同步程式碼的編寫。

事件循環 (Event Loop)

事件循環是 asyncio 的核心,它負責調度和執行協程。當一個協程遇到 await 語句時,它會暫停執行,並將控制權返回給事件循環,這樣其他協程就可以運行。

協程 (Coroutine)

協程是使用 async def 定義的函數,可以被暫停和恢復。協程內部可以使用 await 來等待其他協程或異步操作的完成。

使用 asyncio 的基本範例

下面是一個簡單的範例,展示了如何使用 asyncio 進行非同步程式設計:

import asyncio

# 定義一個協程
async def say_hello():
print("Hello")
await asyncio.sleep(1) # 模擬一個耗時的 I/O 操作
print("World")

# 執行事件循環
async def main():
await say_hello()

# 使用 asyncio.run() 啟動事件循環
if __name__ == "__main__":
asyncio.run(main())

在這個範例中,我們定義了一個名為 say_hello 的協程,它會顯示 "Hello",然後暫停一秒鐘,再顯示 "World"。我們使用 asyncio.run() 啟動事件循環並執行主協程。

事件循環的操作

創建和運行事件循環

除了使用 asyncio.run(),我們還可以手動創建和運行事件循環:

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

這段程式碼首先獲取當前的事件循環,然後運行主協程,最後關閉事件循環。

任務 (Task) 和 Future

在 asyncio 中,任務是對協程的封裝,可以通過 asyncio.create_task() 或 asyncio.ensure_future() 來創建。任務會被調度到事件循環中執行,而 Future 對象則表示一個尚未完成的操作。

task = asyncio.create_task(say_hello())
await task # 等待任務完成

同時運行多個協程

我們可以使用 asyncio.gather() 同時運行多個協程:

async def say_goodbye():
print("Goodbye")
await asyncio.sleep(1)
print("See you later")

async def main():
await asyncio.gather(say_hello(), say_goodbye())

if __name__ == "__main__":
asyncio.run(main())

在這裡,我們定義了另一個協程 say_goodbye(),並使用 asyncio.gather() 同時調用兩個協程。這樣可以更有效地利用等待時間。

錯誤處理

在非同步程式設計中,錯誤處理也很重要。我們可以使用 try-except 來捕獲異常:

async def risky_operation():
raise ValueError("An error occurred!")

async def main():
try:
await risky_operation()
except ValueError as e:
print(f"Caught an error: {e}")

if __name__ == "__main__":
asyncio.run(main())

總結

透過本文,你應該能夠理解如何使用 Python 的 asyncio 模組進行非同步程式設計。掌握事件循環、協程及其運作方式,可以幫助你有效地處理 I/O 密集型任務,提高應用程序的性能。在實際開發中,你可以根據需要選擇合適的方法來實現非同步處理,以達到最佳效果。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.