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

更新於 發佈於 閱讀時間約 6 分鐘

在這篇文章中,我們將深入探討 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 密集型任務,提高應用程序的性能。在實際開發中,你可以根據需要選擇合適的方法來實現非同步處理,以達到最佳效果。

留言
avatar-img
留言分享你的想法!
avatar-img
追極光的北極熊|軟體工程師的小天地
9會員
159內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
2025/04/28
當我們開發程式時,功能能正常運作固然重要,但在資料量變大或執行時間變長時,效能就成為不可忽視的一環。尤其在 Web 應用、資料分析或科學運算中,程式跑得快與否,直接影響使用者體驗與系統成本。
2025/04/28
當我們開發程式時,功能能正常運作固然重要,但在資料量變大或執行時間變長時,效能就成為不可忽視的一環。尤其在 Web 應用、資料分析或科學運算中,程式跑得快與否,直接影響使用者體驗與系統成本。
2025/04/22
嘿,大家好!上篇教學文章我們做出了一個待辦事項清單,已經有點小工具的感覺了吧?今天我們要再升級,來做個「簡單記事本」。這個專案不只可以寫東西,還能存檔、讀檔,甚至換字體大小,感覺就像自己寫了個迷你軟體!
2025/04/22
嘿,大家好!上篇教學文章我們做出了一個待辦事項清單,已經有點小工具的感覺了吧?今天我們要再升級,來做個「簡單記事本」。這個專案不只可以寫東西,還能存檔、讀檔,甚至換字體大小,感覺就像自己寫了個迷你軟體!
2025/04/16
嘿,大家好!走到這一步,我們已經玩過 Tkinter 的基本招式、佈局、事件處理,還搞了些進階元件,應該有點信心了吧?今天我們要把這些功夫練成一套連招,來做個實用的「待辦事項清單」(To-Do List),順便聊聊怎麼把程式寫得更漂亮、更好用。準備好了嗎?這就上場啦!
2025/04/16
嘿,大家好!走到這一步,我們已經玩過 Tkinter 的基本招式、佈局、事件處理,還搞了些進階元件,應該有點信心了吧?今天我們要把這些功夫練成一套連招,來做個實用的「待辦事項清單」(To-Do List),順便聊聊怎麼把程式寫得更漂亮、更好用。準備好了嗎?這就上場啦!
看更多
你可能也想看
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
在模擬群聚行為時,隨著boid的數量越來越多,需要的計算量也會越來越多,導致程式的執行速度也跟著越來越慢,最後甚至於動彈不得。要克服這個問題,在寫程式時使用效率比較好的演算法,就是個不錯的主意。
Thumbnail
在模擬群聚行為時,隨著boid的數量越來越多,需要的計算量也會越來越多,導致程式的執行速度也跟著越來越慢,最後甚至於動彈不得。要克服這個問題,在寫程式時使用效率比較好的演算法,就是個不錯的主意。
Thumbnail
從實際應用中學習 Python 程式設計,提升技能並建立作品集。文章提供八個循序漸進的 Python 專案範例,涵蓋檔案操作、網路爬蟲、Web 應用、自動化腳本、數據分析、遊戲開發、API 互動及應用程式部署,並附上實戰建議及學習資源。
Thumbnail
從實際應用中學習 Python 程式設計,提升技能並建立作品集。文章提供八個循序漸進的 Python 專案範例,涵蓋檔案操作、網路爬蟲、Web 應用、自動化腳本、數據分析、遊戲開發、API 互動及應用程式部署,並附上實戰建議及學習資源。
Thumbnail
本篇文章介紹 Python 的 asyncio 標準庫,說明其用於非同步編程的優勢,並深入探討 await, asyncio.create_task(), asyncio.gather() 的用法與差異,以提升 I/O 密集型應用的效能。
Thumbnail
本篇文章介紹 Python 的 asyncio 標準庫,說明其用於非同步編程的優勢,並深入探討 await, asyncio.create_task(), asyncio.gather() 的用法與差異,以提升 I/O 密集型應用的效能。
Thumbnail
.NET 執行緒池是重要的非同步觀念,async 和 await 底層機制之一。本文探討執行緒池如何有效管理及重複使用執行緒,避免頻繁創建和銷毀執行緒的開銷,並比較 Task.Run 與直接創建 Thread 的差異,以及在精確計時任務方面可能面臨的挑戰。
Thumbnail
.NET 執行緒池是重要的非同步觀念,async 和 await 底層機制之一。本文探討執行緒池如何有效管理及重複使用執行緒,避免頻繁創建和銷毀執行緒的開銷,並比較 Task.Run 與直接創建 Thread 的差異,以及在精確計時任務方面可能面臨的挑戰。
Thumbnail
這篇文章探討非同步編程的優缺點,並提供在設計非同步系統時需要注意的事項。非同步編程允許程式在等待 I/O 操作完成的同時,繼續執行其他工作,提高響應速度和資源利用率。然而,非同步程式設計也增加了系統複雜性,需要謹慎處理錯誤和確保代碼可讀性。
Thumbnail
這篇文章探討非同步編程的優缺點,並提供在設計非同步系統時需要注意的事項。非同步編程允許程式在等待 I/O 操作完成的同時,繼續執行其他工作,提高響應速度和資源利用率。然而,非同步程式設計也增加了系統複雜性,需要謹慎處理錯誤和確保代碼可讀性。
Thumbnail
在這篇文章中,我們將深入探討 Python 中的平行程式設計,特別是使用 threading 和 multiprocessing 模組來實現多執行緒和多進程的應用。這些技術可以幫助我們充分利用現代 CPU 的多核心架構,提高程式的執行效率。
Thumbnail
在這篇文章中,我們將深入探討 Python 中的平行程式設計,特別是使用 threading 和 multiprocessing 模組來實現多執行緒和多進程的應用。這些技術可以幫助我們充分利用現代 CPU 的多核心架構,提高程式的執行效率。
Thumbnail
在寫程式時,重複執行指令是常見需求。Python 提供了兩種迴圈結構:for-in 迴圈和 while 迴圈。for-in 迴圈適合已知迴圈次數或進行容器迭代;while 迴圈則用於不確定迴圈次數的情境。本文將介紹這兩種迴圈的基本用法及練習範例。
Thumbnail
在寫程式時,重複執行指令是常見需求。Python 提供了兩種迴圈結構:for-in 迴圈和 while 迴圈。for-in 迴圈適合已知迴圈次數或進行容器迭代;while 迴圈則用於不確定迴圈次數的情境。本文將介紹這兩種迴圈的基本用法及練習範例。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News