在本教程中,我們將學習 Python 中的協程。我們將詳細討論 Python 中的協程、子程序、協程的執行和協程的關閉。
在開始學習協程之前,我們必須對 Python 中的子程序有一個基本的了解。因此,我們將從本教程中的 Python 子例程開始。
Python 子程序
眾所周知,Python 中的函數,我們可能知道也可能不知道這些 Python 函數也被稱為過程、子過程或子程序。
通常,Python 中的函數是一個打包的指令序列,作為一個單元來執行代碼中的某項任務。當我們把複雜函數的邏輯分成幾個獨立的步驟,像一個獨特的函數(嵌套函數等)一樣工作時。),那麼這些助手或者主函數中的嵌套函數在 Python 中被稱為子程序。
我們通過 Python 中負責協調的主函數調用子程序,同時在函數中使用子程序。Python 中的所有子程序只有一個入口點,即啟動主函數。
主要功能
看到上面給出的圖,我們很容易得出結論,在使用子程序的時候需要主函數來協調子程序之間的關係,主函數也是 Python 中子程序的唯一入口點。
什麼是科羅廷?
現在,在這一節中,我們將討論基本上是子程序一般化的協程。
協同通常用於在一段時間內(周期性地)主動放棄(讓步)控制的進程的協同多任務處理。當空閑時,也可以使用協程來同時運行多個應用。
在花冠中,花冠不同於線;決定何時切換協程的是程序員和編程語言,而在線程的情況下,操作系統安排線程之間的切換。
協程和子程序的區別
| 協程 | 子程序 |
| 與子程序不同,Coroutines 有多個入口點。 | 子程序只有一個入口點,即主函數。 |
| 我們只能從單點暫停和恢復 Python 子程序的執行,只能從起點恢復。 | 我們可以從函數中的多個點暫停和恢復 Python 中 coroutines 的執行,也可以從上次暫停的地方恢復執行。 |
| 與子程序不同,我們沒有任何主要的 Python 協同函數來命令和協調它們的執行。 | 在 Python 子程序中,主函數協調多個子程序並控制它們的執行。 |
| 協程是合作的,因為當我們執行它們時,它們一起形成了一個管道結構。 | 子程序形成線性執行結構。 |
| 在協程中,我們有一個顯示輸入數據結果的協程。 | 對於子程序,子程序中給出的數據處理結果由主函數顯示。 |
Python 中的協程
協程與 Python 中的生成器非常相似,但是協程在 yield(放棄)語句中做了一些修改,並提供了一些額外的方法。Python coroutines 也能夠使用輸入數據,而生成器只能產生用於函數迭代的數據。
在版本高於 2.5 的 Python 中,我們可以觀察到 coroutines 的 yield
語句中引入了一個微小的變化,在這個變化之後,yield
語句可以作為一個表達式使用。
例:右側收益率賦值,即 LineOfCode =(收益率)
我們在程序中發送給協程的任何值都將被協程捕獲,並且只通過 yield 表達式返回。我們只能通過 send()函數向協程發送一個值。
考慮下面程序中的給定協程,該程序將只打印前綴中有“官員”的姓名,我們將使用 send() 函數將姓名發送給協程。
示例:
# Default function to search prefix
def print_name(prfx):
print("Coroutine object searching for the prefix: {}".format(prfx)) # Searching for prefix
while True:
GivenName = (yield)
if prfx in GivenName: # If required prefix match
print(GivenName) # Print given name
CorouteObject = print_name("Officer") # Taking prefix = Officer for coroutine object
# Taking names as input from user
Name1 = input("Enter first name: ")
Name2 = input("Enter second name: ")
Name3 = input("Enter third name: ")
CorouteObject.__next__() # using _next_() method to call coroutine
# sending input data to coroutine with send() method
CorouteObject.send(Name1)
CorouteObject.send(Name2)
CorouteObject.send(Name3)
輸出:
Enter first name: Alex
Enter second name: Officer Steve Rogers
Enter third name: Officer Natasha Widow
Coroutine object searching for the prefix: Officer
Officer Steve Rogers
Officer Natasha Widow
解釋-
所以,在上面的程序中我們可以看到,我們已經從用戶那裡取了三個名字作為輸入數據,我們已經通過 send() 方法將用戶輸入數據發送到函數中定義的協程。我們在協程中使用了“officer”關鍵字來搜索名字中有 Officer 前綴的名字,協程將只打印這些匹配的名字,正如我們在輸出中看到的那樣。
執行共同訴訟
在 Python 中,協程的執行與生成器非常相似。當我們在程序中調用協程時,什麼也不會發生;它將只運行以下兩個響應:send()和 next()函數。
我們可以在上面的例子中清楚地觀察到;只有在我們調用了程序中的 next()方法之後,協程才會開始執行。調用協程後,執行前進到產生第一個表達式。
之後,協程的執行暫停,等待值發送到協程對象。在第一個值被發送到協程對象後,它檢查所需的前綴是否存在,如果存在,那麼對象將打印帶有前綴的名稱。在打印名稱後,它會經歷一個連續的循環,直到再次遇到 name = (yield)表達式。
結案陳詞
要關閉協程,我們必須在程序中使用 close() 函數。當我們關閉協程時,它會產生一個異常,即 GeneratorExit 異常,我們可以用捕獲異常的正常方式來捕獲它。
示例-
# Default function to search prefix
def print_name(prfx):
print("Coroutine object searching for the prefix: {}".format(prfx)) # Searching for prefix
# Using excption handling by try and except
try:
while True:
GivenName = (yield)
if prfx in GivenName: # If required prefix match
print(GivenName) # Print given name
except GeneratorExit: # Handling GeneratorExit exception
print("Now we have closed the coroutine!!")
CorouteObject = print_name("Officer") # Taking preifx = Officer for coroutine object
CorouteObject.__next__() # using _next_() method
# sending input data to coroutine with send() method
CorouteObject.send("Alexa")
CorouteObject.send("Officer Tony Stark")
CorouteObject.send("Officer Steve Rogers")
# closing the coroutine
CorouteObject.close()
輸出:
Coroutine object searching for the prefix: Officer
Officer Tony Stark
Officer Steve Rogers
Now we have closed the coroutine!!
我們必須記住,如果我們試圖在關閉協同對象後向協同對象發送值,程序將在輸出中引發一個 StopIteration 異常。
通過鏈接協同創建管道結構
我們可以使用協程創建一個管道結構。在我們將協程鏈接在一起之後,我們可以使用 push()方法通過創建的管道結構推送給定的數據。要在帶有 coroutines 的程序中創建管道結構,我們必須注意以下事項:
我們必須給出一個初始源,即生產者,它將導出完整的管道結構。一般來說,生產者本身並不是一個附屬品,他們只是一個簡單的方法。
我們必須在管道的末端創建一個接收器,該接收器將充當管道的端點。接收器是協同管道中的一個點,它可以收集所有的輸入數據並顯示出來。
了解以下流水線結構的協程。
示例:
# Defining producer for the pipeline
def producer(GivenSentence, NextCoroutine):
tokens = GivenSentence.split(" ") # splitting sentence
for token in tokens: # iterating over tokens
NextCoroutine.send(token)
NextCoroutine.close() # closing coroutine
# Defining pattern filter for the pipeline structure
def pattern_filter(SearchPattern = "ing", NextCoroutine = None):
print("In the input sentence, we are searching for words that end with{}".format(SearchPattern)) # Searching for pattern
try:
while True:
token = (yield) # yielding tokens
if SearchPattern in token:
NextCoroutine.send(token) # Sending tokens
except GeneratorExit: # Exception handling for GeneratorExit exception
print("We are done with filtering the given input sentence!!")
# Defining sink for the pipeline
def print_token():
print("I'm sink in the pipeline and I am used to print the tokens given.")
try:
while True:
token = (yield) # yielding tokens
print(token) # printing the tokens from sink
except GeneratorExit:
print("Now we are done with printing!")
# Taking sink variable
PrintToken = print_token()
PrintToken.__next__() # calling sink
# Taking Pattern filter variable
PatternFilter = pattern_filter(NextCoroutine = PrintToken)
PatternFilter.__next__() # calling pattern filter
# Taking a sentence for the producer in the pipeline
GivenSentence = "Steve rogers is running very fast to chase down a train moving with high speed"
producer(GivenSentence, PatternFilter) # calling producer
輸出:
I'm sink in the pipeline, and I am used to printing the tokens given.
In the input sentence, we are searching for words that end with ing
running
moving
We are done with filtering the given input sentence!!
解釋-
這就是我們如何使用用多個協同創建的管道並過濾輸入數據。過濾或合成的數據將顯示在管道的接收器上,正如我們在上面的輸出中看到的。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/304169.html