Python 简明教程
Python - Coroutines
Python Coroutines 是编程中的基本概念,它扩展了传统函数的功能。它们对于异步编程和复杂的数据处理管道特别有用。
Coroutines 是函数和生成器的概念的扩展。它们被设计用于执行协作多任务并管理异步操作。
在传统函数中,即单一入口和出口点的子例程,而协程可以在恢复的时候暂停和恢复执行,使其具有很高的灵活性。
Key Characteristics of Coroutines
以下是 Python 中协程的关键特性 −
-
Multiple Entry Points: 协程不像传统函数那样局限于单一入口点。当它们遇到 yield 语句时,可以在特定点暂停执行,然后稍后恢复。这使协程能够处理等待异步数据或处理此数据的复杂工作流。
-
No Central Coordinator: 当我们看到传统函数(即子例程),它通常由主函数协调;而协程则更独立地运行。它们可以在管道模式下相互交互,其中数据流经一系列协程,而每个协程都执行不同的任务。
-
Cooperative Multitasking: 协程启用协作多任务。这意味着,调度程序控制协程的产生和恢复,而不是依赖操作系统或运行时在任务之间切换,从而允许对执行流进行更细粒度的控制。
Subroutines Vs. Coroutines
Subroutines 是具有单个入口点且没有固有暂停或恢复执行机制的传统函数。它们按定义的顺序调用,并处理具有简单控制流的任务。
Coroutines 是具有多个入口点的高级函数,可以暂停和恢复其执行。它们对于需要异步执行、复杂控制流和数据管道的重要任务十分有用。它们支持协作多任务,允许调度程序控制任务之间的执行切换。
下表有助于理解子例程和协程之间的关键差异和相似之处,让我们更容易掌握它们在编程中的各自作用和功能。
Execution of Coroutines
Coroutines 由 * next ()* 方法启动,它启动协程并将执行推进到第一个 yield
语句。然后协程等待发送到它其中的一个值。 send() 方法用于向协程发送值,这些值随后可以处理这些值并可能产生结果。
Example of Basic Coroutine
协程使用既可以发送又可以接收值的 yield
语句。与为迭代产生值的 generator 不同,协程通常使用 yield
来接收输入并根据该输入执行动作。以下是 Python 协程的基本示例 −
def print_name(prefix):
print(f"Searching prefix: {prefix}")
while True:
name = (yield)
if prefix in name:
print(name)
# Instantiate the coroutine
corou = print_name("Welcome to")
# Start the coroutine
corou.__next__()
# Send values to the coroutine
corou.send("Tutorialspoint")
corou.send("Welcome to Tutorialspoint")
Output
Searching prefix: Welcome to
Welcome to Tutorialspoint
Closing a Coroutine
Coroutines 可以无限期运行,因此在不需要它们时正确关闭它们非常重要。 close() 方法终止协程并处理清理。如果我们尝试向已关闭的协程发送数据,它将引发 StopIteration exception.
Example
以下是 Python 中关闭协程的示例 −
def print_name(prefix):
print(f"Searching prefix: {prefix}")
try:
while True:
name = (yield)
if prefix in name:
print(name)
except GeneratorExit:
print("Closing coroutine!!")
# Instantiate and start the coroutine
corou = print_name("Come")
corou.__next__()
# Send values to the coroutine
corou.send("Come back Thank You")
corou.send("Thank you")
# Close the coroutine
corou.close()
Output
Searching prefix: Come
Come back Thank You
Closing coroutine!!
Chaining Coroutines for Pipelines
Coroutines 可以链接在一起形成处理管道,允许数据流经一系列阶段。这对于分阶段处理数据序列特别有用,其中每个阶段执行特定任务。
Example
以下是展示用于管道的协程链接示例 −
def producer(sentence, next_coroutine):
'''
Splits the input sentence into tokens and sends them to the next coroutine.
'''
tokens = sentence.split(" ")
for token in tokens:
next_coroutine.send(token)
next_coroutine.close()
def pattern_filter(pattern="ing", next_coroutine=None):
'''
Filters tokens based on the specified pattern and sends matching tokens to the next coroutine.
'''
print(f"Searching for {pattern}")
try:
while True:
token = (yield)
if pattern in token:
next_coroutine.send(token)
except GeneratorExit:
print("Done with filtering!!")
next_coroutine.close()
def print_token():
'''
Receives tokens and prints them.
'''
print("I'm the sink, I'll print tokens")
try:
while True:
token = (yield)
print(token)
except GeneratorExit:
print("Done with printing!")
# Setting up the pipeline
pt = print_token()
pt.__next__()
pf = pattern_filter(next_coroutine=pt)
pf.__next__()
sentence = "Tutorialspoint is welcoming you to learn and succeed in Career!!!"
producer(sentence, pf)
Output
I'm the sink, I'll print tokens
Searching for ing
welcoming
Done with filtering!!
Done with printing!