Python 事件驅動編程

在本教程中,我們將學習事件驅動編程以及可以用來進行 Python 事件驅動編程的 Python 模塊(Asyncio)。

事件驅動編程

最終,程序的流程依賴於事件,而專註於事件的編程稱為事件驅動編程。我們只處理並行或順序模型,但是現在我們將討論異步模型。遵循事件驅動編程概念的編程模型稱為異步模型。事件驅動編程的工作依賴於程序中發生的事件。

除此之外,它還依賴於程序的事件循環,該循環總是在程序中監聽新的傳入事件。一旦一個事件循環在程序中開始,那麼只有事件將決定執行什麼和以什麼順序執行。

查看下面的事件循環流程圖,了解事件驅動編程中事件的工作方式:

事件驅動pexpect模塊

asyncio模塊是在 3.4 版本中添加到 Python 中的,它在 Python 的所有更高版本中都可用。Asyncio 模塊為使用程序中的 coroutines 將並發代碼編寫為單線程提供了非常好的基礎設施。

在 Python 的 asyncio模塊中,在進行事件驅動編程時使用了以下不同的概念:

  • 事件循環
  • 期貨
  • 協程
  • @asyncio .裝飾程式
  • 任務
  • 運輸
  • 和協議

讓我們詳細了解 asyncio模塊使用的所有這些不同的概念,並了解它們在進行事件驅動編程時是如何工作的。

事件循環

事件循環是 asyncio模塊的一項功能,用於處理計算程序中發生的所有事件。當整個程序正在執行時,事件循環的行為就像是在繞路,它還會跟蹤已執行的事件和新的傳入事件。asyncio模塊的一個主要優點是,每個進程只允許一個事件循環。

asyncio模塊中,我們有一些方法可以用來管理代碼中的事件循環。asyncio模塊中提供了以下方法。

  • time() – 我們可以根據事件循環中存在的內部時鐘,用這個方法將當前時間返回給用戶。
  • loop = get_event_loop() – 通過使用這個方法,我們將根據程序中執行的當前上下文得到事件循環作為回報。
  • call_soon(CallbackFunction,ArgumentGiven) – 有了這個函數,我們可以安排一個回調函數儘快被調用。當控件返回到事件循環並且 call_soon()返回後,參數中給出的回調函數將被調用。
  • call late(time to _ delived,CallbackFunction,ArgumentGiven) – 使用這個方法,我們可以安排在我們提供的時間延遲(以秒為單位)之後調用方法中給出的回調函數。
  • new_event_loop() – 使用這個方法,我們可以創建並返回一個新的事件 loop 項目。
  • set_event_loop() – 藉助這個方法,我們可以為從程序執行到循環的當前上下文設置事件循環。
  • run_forever() – 通過在程序中使用 loop.run_forever()方法,我們可以運行一個循環,直到調用 stop()方法。

現在,我們將在下面的示例中查看一個 Python 程序,其中我們將使用事件循環方法,即 get_event_loop()方法。通過使用這種方法,我們將打印我們在事件內部給出的命令。

示例:看看下面這個包含事件循環的 Python 程序:


# Importing asyncio module in the program
import asyncio
# A default function with event loops method
def loopText(loop):
   # A text printing command
       print('Printing this text through the event loop')
       loop.stop() # Stopping the loop
loop = asyncio.get_event_loop() # Using get_event_loop() method to print the text
loop.call_soon(loopText, loop) # Using call_soon() method from event loops
loop.run_forever() # run_forever() on event loop
loop.close() # Closing the loop

輸出

Printing this text through the event loop

說明:

我們首先在程序中導入了 asyncio模塊,以使用事件循環方法。

之後,我們定義了一個默認函數,在這個函數中,我們給出了「loop」作為參數,並在函數內部給出了打印命令。我們使用事件循環中的 stop()方法來停止事件。

之後,我們在循環參數上使用 get_event_loop()方法打印默認函數中的文本。然後,在 call_soon()事件循環方法中,我們使用函數的函數名和參數作為參數。最後,我們使用了 run_forever()和 close()事件循環方法。

期貨

asyncio模塊中給出的未來類與 concurrent.futures 方法兼容。asyncio模塊中給出的未來類代表程序中的計算,這還沒有完成。

期貨和期貨之間有一些主要的區別

  • 我們在將來的類中用 add_done_callback()方法註冊的回調函數將始終只通過事件循環中的 call_soon()方法來調用。
  • future 類中的 exception()和 result()方法不會接受超時或給定時間的參數,當這些函數的 future 尚未完成時,它們會在輸出中顯示一個錯誤。
  • 我們不能將 asyncio.futures.Future 類與 concurrent.futures 包中的 as_completed()或 wait()函數一起使用,因為它與它們不兼容。

現在,我們將在下面的示例中查看一個 Python 程序,其中我們將使用 asyncio模塊中的未來類方法,並在輸出中打印文本。

示例:


# Importing asyncio module in the program
import asyncio
# A default function from the async module using future parameter in it
async def myFunction(future):
   await asyncio.sleep(2) # Using sleep() function of asyncio module
   future.set_result('This text is printed using future class methods!') # Printing text from future parameter
# Using get_event_loop() method from event loop
loop = asyncio.get_event_loop()
future = asyncio.Future() # Using future() class method
# Calling default function from future class method
asyncio.ensure_future(myFunction(future))
# Using try & finally method future parameter of function
try:
   loop.run_until_complete(future)
   print(future.result()) # printing result from future class
finally:
      loop.close() # finally closing the loop

輸出

This text is printed using future class methods!

說明:

我們首先定義了一個默認函數,即「myFunction」,future 作為參數。在函數內部,我們使用 sleep()方法作為執行的兩秒暫停。

然後,我們使用未來的類方法給出了我們想要打印在結果中的文本。我們在程序中使用了事件循環中的 get_event_loop 方法。然後,我們對默認函數中給出的 future 參數使用了 future()類方法。

現在,我們可以在輸出中打印文本,就像我們在其中使用了未來一樣。為了打印輸出中的文本,我們使用了 try 和 finish 方法,其中 try 方法調用了 printing 命令,finish 方法使用 close()方法關閉了循環。

協程

asyncio模塊內部的協同概念非常類似於線程模塊線程對象中的協同概念。

asyncio模塊中的協同概念是子程序概念的推廣形式。

我們甚至可以在程序執行期間掛起一個協程,這樣掛起的協程將等待用戶給出的外部處理。只有在外部處理完成後,暫停的協程才會返回到上次暫停的位置。

asyncio模塊協程中,我們可以使用以下兩種方式來幫助我們在程序中實現協程:

  1. @asyncio .裝飾程式
  2. 異步定義函數()

讓我們通過在 Python 程序中使用它們的實現來理解這兩種方式。

1 .@asyncio .裝飾例程〔t1〕

我們可以利用帶有 asyncio模塊裝飾器的生成器,即@asyncio.coroutine 裝飾器,在程序內部實現協程。我們可以通過下面的例子理解協程和 decorator 的實現。

示例:看看下面的 Python 程序:


# Importing asyncio module in the program
import asyncio
# Using @asyncio.coroutine decorator to implement coroutines
@asyncio.coroutine
# Using a default function with coroutine implementation
def operationCoroutine():
    print("This text is present inside the coroutine of the asyncio module!") # Printing text inside coroutine
loop = asyncio.get_event_loop() # Using get_event_loop() method to print text
try:
     loop.run_until_complete(operationCoroutine()) # Using run_until_complete() loop method on default function
finally:
    loop.close() # closing the loop

輸出

This text is present inside the coroutine of the asyncio module!

說明:

導入 asyncio模塊後,我們使用了@asyncio.coroutine 裝飾器。然後,我們使用一個默認函數來使用協程方法來獲取文本。之後,我們使用事件循環中的 get_event_loop()方法打印輸出中的文本。最後,我們對默認函數使用了「try and finally」方法,並使用 close()函數關閉了程序中的循環。

2。異步定義函數()

我們可以說 async def 函數()是 asyncio模塊實現協程的最通用的方法。我們可以通過下面的例子理解這個用 def 函數()實現 coroutines 的方法。

示例:看看下面的 Python 程序:


# Importing asyncio module in the program
import asyncio
# Using async def function() to implement coroutines
async def operationCoroutine():
   print("This text is present inside the coroutine of the asyncio module!") # Printing text inside coroutine
loop = asyncio.get_event_loop() # Using get_event_loop() method to print text
try:     loop.run_until_complete(operationCoroutine()) # Using run_until_complete() loop method on default function
finally:
    loop.close() # closing the loop

輸出

This text is present inside the coroutine of the asyncio module!

說明:

像第一種實現協程的方法一樣,我們在這個方法中也遵循了同樣的路徑。在這個方法中,我們沒有使用裝飾器,然後為 coroutines 定義默認函數,而是直接使用 asyncio模塊的 async def operationCoroutine()函數來實現 coroutines。

任務

Tasks 是 asyncio模塊中給出的一個子類,負責在事件循環中以並行執行的方式執行 asyncio 協程。我們可以通過使用一個 Python 程序來執行協同工作來理解任務子類的工作。


# Importing asyncio module in the program
import asyncio
# Importing time module
import time
# Using async default function()
async def Task_ex(n):
   time.sleep(2) # sleep() function of time module
   print("Loop event is processing coroutine no: {}".format(n)) # given printing tasks to print in output
# Generating tasks with async default function
async def Generator_task():
       # looping over tasks using for loop
       for i in range(10):
             asyncio.ensure_future(Task_ex(i))
        # After completing loop
       print("All given tasks are completed")
       asyncio.sleep(2)
loop = asyncio.get_event_loop() # printing in output using event loop method
loop.run_until_complete(Generator_task()) # Running the loop
loop.close() # Closing the loop

輸出

Loop event is processing coroutine no: 0
Loop event is processing coroutine no: 1
Loop event is processing coroutine no: 2
Loop event is processing coroutine no: 3
Loop event is processing coroutine no: 4
Loop event is processing coroutine no: 5
Loop event is processing coroutine no: 6
Loop event is processing coroutine no: 7
Loop event is processing coroutine no: 8
Loop event is processing coroutine no: 9
All given tasks are completed

說明:

我們在程序中導入了 asyncio 和時間模塊來使用它的功能。然後,我們使用異步默認函數來設置打印已處理的協程的任務。

我們使用時間模塊的 sleep()函數,在打印每個執行的協程後,給出 2 秒的休息時間。

然後,我們使用另一個異步默認函數來設置其中任務的循環。完成循環後,該功能將打印「任務已完成」最後,我們使用事件循環方法來運行和關閉程序中的循環。

運輸

Transports 是 asyncio模塊中提供給我們的類,我們可以使用它們在程序中實現各種類型的通信。傳輸類不是線程安全的,我們總是必須在通信通道建立後將它們與協議實例配對。

在 asyncio 傳輸類中,程序中可以從基本傳輸類繼承以下類型的傳輸:

  1. 數據報傳輸:數據報傳輸是我們用來發送數據的接口。
  2. 讀傳輸:讀傳輸是只讀模式傳輸類的接口。
  3. 寫傳輸:這個傳輸是繼承的傳輸類的接口,只有隻寫模式。
  4. 基本子流程傳輸:基本子流程傳輸類的功能與基本傳輸類非常相似。

在所有上述繼承的傳輸類中,只有以下不同類型的方法隨後從基本傳輸類中過渡出來:

  1. is_closing(): 只有當參數中給定的傳輸類已經關閉並且正在關閉時,此方法才會返回 true。
  2. close(): 此方法用於關閉程序中正在運行的當前傳輸類。
  3. get_protocol(): 我們可以使用 transport 類中的 get_protocol()方法來獲取當前協議作為回報。
  4. get_extra_info(className,default = none ):我們可以使用這個方法獲取一些關於我們在參數中給出的傳輸類的附加信息。

協議

asyncio模塊中,我們提供了幾個基類,可以用它們在子類中實現我們的網絡協議。我們可以將這樣的類與傳輸類結合使用。該協議將請求輸出數據並解析輸入數據,而傳輸類負責緩衝和實際輸入/輸出

以下是三類協議:

  1. 協議類:它是協議中的基類,我們可以用它來實現與 SSL 和 TCP 傳輸一起使用的流協議。
  2. 數據報協議類:它是協議中的另一個基類,我們可以用來實現與 UDP 傳輸一起使用的數據報協議。
  3. 子進程協議類:我們可以使用協議中的這個基類來實現使用一組單向管道來傳遞子進程的各種協議。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/276742.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-19 13:20
下一篇 2024-12-19 13:20

相關推薦

  • Python列表中負數的個數

    Python列表是一個有序的集合,可以存儲多個不同類型的元素。而負數是指小於0的整數。在Python列表中,我們想要找到負數的個數,可以通過以下幾個方面進行實現。 一、使用循環遍歷…

    編程 2025-04-29
  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python周杰倫代碼用法介紹

    本文將從多個方面對Python周杰倫代碼進行詳細的闡述。 一、代碼介紹 from urllib.request import urlopen from bs4 import Bea…

    編程 2025-04-29
  • 如何查看Anaconda中Python路徑

    對Anaconda中Python路徑即conda環境的查看進行詳細的闡述。 一、使用命令行查看 1、在Windows系統中,可以使用命令提示符(cmd)或者Anaconda Pro…

    編程 2025-04-29
  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Python字典去重複工具

    使用Python語言編寫字典去重複工具,可幫助用戶快速去重複。 一、字典去重複工具的需求 在使用Python編寫程序時,我們經常需要處理數據文件,其中包含了大量的重複數據。為了方便…

    編程 2025-04-29
  • python強行終止程序快捷鍵

    本文將從多個方面對python強行終止程序快捷鍵進行詳細闡述,並提供相應代碼示例。 一、Ctrl+C快捷鍵 Ctrl+C快捷鍵是在終端中經常用來強行終止運行的程序。當你在終端中運行…

    編程 2025-04-29
  • Python程序需要編譯才能執行

    Python 被廣泛應用於數據分析、人工智能、科學計算等領域,它的靈活性和簡單易學的性質使得越來越多的人喜歡使用 Python 進行編程。然而,在 Python 中程序執行的方式不…

    編程 2025-04-29
  • Python清華鏡像下載

    Python清華鏡像是一個高質量的Python開發資源鏡像站,提供了Python及其相關的開發工具、框架和文檔的下載服務。本文將從以下幾個方面對Python清華鏡像下載進行詳細的闡…

    編程 2025-04-29

發表回復

登錄後才能評論