事件驅動程式設計



事件驅動程式設計關注事件。最終,程式的流程取決於事件。到目前為止,我們一直在處理順序或並行執行模型,但是具有事件驅動程式設計概念的模型稱為非同步模型。事件驅動程式設計依賴於一個始終監聽新傳入事件的事件迴圈。事件驅動程式設計的工作依賴於事件。一旦事件迴圈執行,事件就決定執行什麼以及按什麼順序執行。下面的流程圖將幫助您理解其工作原理:

Driven

Python模組 – Asyncio

Asyncio模組在Python 3.4中新增,它提供使用協程編寫單執行緒併發程式碼的基礎設施。以下是Asyncio模組使用的不同概念:

事件迴圈

事件迴圈是一種處理計算程式碼中所有事件的功能。它在整個程式執行過程中迴圈執行,並跟蹤事件的傳入和執行。Asyncio模組允許每個程序只有一個事件迴圈。以下是Asyncio模組提供的一些用於管理事件迴圈的方法:

  • loop = get_event_loop() − 此方法將提供當前上下文的事件迴圈。

  • loop.call_later(time_delay,callback,argument) − 此方法安排在給定的time_delay秒後呼叫的回撥函式。

  • loop.call_soon(callback,argument) − 此方法安排儘快呼叫的回撥函式。回撥函式在call_soon()返回後以及控制權返回到事件迴圈時呼叫。

  • loop.time() − 此方法用於根據事件迴圈的內部時鐘返回當前時間。

  • asyncio.set_event_loop() − 此方法將當前上下文的事件迴圈設定為loop。

  • asyncio.new_event_loop() − 此方法將建立並返回一個新的事件迴圈物件。

  • loop.run_forever() − 此方法將一直執行,直到呼叫stop()方法。

示例

以下事件迴圈示例使用get_event_loop()方法列印hello world。此示例取自Python官方文件。

import asyncio

def hello_world(loop):
   print('Hello World')
   loop.stop()

loop = asyncio.get_event_loop()

loop.call_soon(hello_world, loop)

loop.run_forever()
loop.close()

輸出

Hello World

Futures

這與concurrent.futures.Future類相容,該類表示尚未完成的計算。asyncio.futures.Future和concurrent.futures.Future之間存在以下區別:

  • result()和exception()方法不帶超時引數,並在future尚未完成時引發異常。

  • 使用add_done_callback()註冊的回撥函式始終透過事件迴圈的call_soon()呼叫。

  • asyncio.futures.Future類與concurrent.futures包中的wait()和as_completed()函式不相容。

示例

以下示例將幫助您瞭解如何使用asyncio.futures.future類。

import asyncio

async def Myoperation(future):
   await asyncio.sleep(2)
   future.set_result('Future Completed')

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
   loop.run_until_complete(future)
   print(future.result())
finally:
   loop.close()

輸出

Future Completed

協程

Asyncio中協程的概念類似於threading模組下標準Thread物件的概念。這是子例程概念的泛化。協程可以在執行過程中暫停,以便等待外部處理,並在外部處理完成時從停止點返回。以下兩種方法可以幫助我們實現協程:

async def function()

這是在Asyncio模組下實現協程的一種方法。下面是相應的Python指令碼:

import asyncio

async def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

輸出

First Coroutine

@asyncio.coroutine 裝飾器

實現協程的另一種方法是使用@asyncio.coroutine裝飾器利用生成器。下面是相應的Python指令碼:

import asyncio

@asyncio.coroutine
def Myoperation():
   print("First Coroutine")

loop = asyncio.get_event_loop()
try:
   loop.run_until_complete(Myoperation())

finally:
   loop.close()

輸出

First Coroutine

任務

Asyncio模組的此子類負責以並行方式在事件迴圈中執行協程。以下Python指令碼是並行處理一些任務的示例。

import asyncio
import time
async def Task_ex(n):
   time.sleep(1)
   print("Processing {}".format(n))
async def Generator_task():
   for i in range(10):
      asyncio.ensure_future(Task_ex(i))
   int("Tasks Completed")
   asyncio.sleep(2)

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

輸出

Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9

傳輸

Asyncio模組提供傳輸類來實現各種型別的通訊。這些類不是執行緒安全的,並且在建立通訊通道後始終與協議例項配對。

以下是繼承自BaseTransport的不同型別的傳輸:

  • ReadTransport − 這是隻讀傳輸的介面。

  • WriteTransport − 這是隻寫傳輸的介面。

  • DatagramTransport − 這是傳送資料的介面。

  • BaseSubprocessTransport − 類似於BaseTransport類。

以下是BaseTransport類的五種不同的方法,這些方法隨後會貫穿四種傳輸型別:

  • close() − 它關閉傳輸。

  • is_closing() − 如果傳輸正在關閉或已關閉,此方法將返回true。

  • get_extra_info(name, default = none) − 這將提供有關傳輸的一些額外資訊。

  • get_protocol() − 此方法將返回當前協議。

協議

Asyncio模組提供基類,您可以對其進行子類化以實現您的網路協議。這些類與傳輸一起使用;協議解析傳入資料並請求寫入傳出資料,而傳輸負責實際的I/O和緩衝。以下是三個協議類:

  • Protocol − 這是用於實現與TCP和SSL傳輸一起使用的流協議的基類。

  • DatagramProtocol − 這是用於實現與UDP傳輸一起使用的分組協議的基類。

  • SubprocessProtocol − 這是用於實現透過一組單向管道與子程序通訊的協議的基類。

廣告
© . All rights reserved.