事件驅動程式設計
事件驅動程式設計關注事件。最終,程式的流程取決於事件。到目前為止,我們一直在處理順序或並行執行模型,但是具有事件驅動程式設計概念的模型稱為非同步模型。事件驅動程式設計依賴於一個始終監聽新傳入事件的事件迴圈。事件驅動程式設計的工作依賴於事件。一旦事件迴圈執行,事件就決定執行什麼以及按什麼順序執行。下面的流程圖將幫助您理解其工作原理:
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 − 這是用於實現透過一組單向管道與子程序通訊的協議的基類。