答案是生成器通过yield暂停和send()接收数据实现协程,具备双向通信能力,是async/await的底层基础,理解它有助于掌握Python异步编程原理。

Python函数通过生成器函数实现协程,核心在于
yield
generator.send()
Python函数简单协程的创建与使用,本质上是利用了生成器的双向通信能力。一个生成器函数,当它包含
yield
yield
send()
说起协程,很多人可能首先想到
async/await
生成器最大的特点是它的“暂停”和“恢复”能力。一个普通的函数,一旦开始执行,就会一直运行到结束或遇到错误。但生成器不同,每当它遇到
yield
yield
next()
send()
立即学习“Python免费学习笔记(深入)”;
而
send()
yield
generator.send(value)
value
yield
举个例子,一个简单的协程可能看起来像这样:
def simple_coroutine():
    print("Coroutine started, waiting for first value...")
    x = yield  # 第一次暂停,等待外部发送数据
    print(f"Received x: {x}, waiting for second value...")
    y = yield x * 2 # 第二次暂停,发送 x*2 并等待新的数据
    print(f"Received y: {y}, Coroutine finished.")
    return "Done"
# 创建并启动协程
my_coro = simple_coroutine()
next(my_coro) # 启动协程,执行到第一个 yield 并暂停,输出 "Coroutine started..."
try:
    # 发送第一个值到协程
    result1 = my_coro.send(10) # 10 成为 yield 的返回值,赋给 x
    print(f"External received from coroutine: {result1}") # 接收到 x * 2 (即 20)
    # 发送第二个值
    result2 = my_coro.send(5) # 5 成为第二个 yield 的返回值,赋给 y
    print(f"External received from coroutine: {result2}") # 理论上这里不会有返回值,因为协程会执行到结束
except StopIteration as e:
    print(f"Coroutine finished with return value: {e.value}")
这段代码展示了协程如何通过
yield
send()
next(my_coro)
yield
yield
send()
None
在生成器协程中,数据传递和异常处理是其实现复杂逻辑的关键。理解这些机制,能让你更好地构建协作式的程序。
数据传递: 如前所述,
generator.send(value)
yield
send()
value
yield
一个常见的“陷阱”是,你不能在协程启动(即第一次运行到
yield
send()
None
yield
next(generator)
generator.send(None)
yield
异常处理: 生成器协程也支持异常的注入和处理,这通过
generator.throw(type, value=None, traceback=None)
def error_handling_coroutine():
    print("Coroutine started.")
    try:
        data = yield
        print(f"Received data: {data}")
    except ValueError as e:
        print(f"Caught ValueError: {e}")
    except Exception as e:
        print(f"Caught general exception: {e}")
    finally:
        print("Coroutine cleanup.")
    yield "Finished processing"
my_error_coro = error_handling_coroutine()
next(my_error_coro) # 预激
try:
    my_error_coro.send("Hello") # 正常发送数据
    my_error_coro.throw(ValueError, "Something went wrong!") # 注入一个 ValueError
    my_error_coro.send("This won't be reached") # 这行代码不会执行,因为协程已经处理了异常或终止
except StopIteration as e:
    print(f"Coroutine ended: {e.value}")在这个例子中,
throw()
yield
ValueError
try...except
throw()
关闭协程:
generator.close()
close()
yield
GeneratorExit
RuntimeError
def cleanup_coroutine():
    print("Cleanup coroutine started.")
    try:
        yield
    except GeneratorExit:
        print("GeneratorExit caught, performing cleanup...")
    finally:
        print("Final cleanup always runs.")
    print("Cleanup coroutine finished.")
my_cleanup_coro = cleanup_coroutine()
next(my_cleanup_coro)
my_cleanup_coro.close() # 关闭协程这些机制共同构成了生成器协程的强大之处,使得它们能够实现复杂的控制流和状态管理。
这是一个非常好的问题,尤其是在Python 3.5引入
async/await
主要区别:
语法层面:
yield
yield from
async/await
send()
throw()
close()
async/await
async def
await
语义与意图:
yield
async/await
await
生态系统与工具支持:
asyncio
async/await
asyncio
aiohttp
FastAPI
我们还需要学它吗?
我的答案是:绝对需要! 尽管
async/await
async/await
yield from
Tornado
asyncio
yield
所以,即便你现在主要使用
async/await
以上就是Python函数怎样用生成器函数实现协程 Python函数简单协程的创建与使用教程的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                
                                
                                
                                
                                
                                
                                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号