0

0

Python await 与 yield from 的区别

冷漠man

冷漠man

发布时间:2026-02-22 14:40:03

|

217人浏览过

|

来源于php中文网

原创

await只能在async函数中使用,因其是协程调度原语,依赖事件循环接管控制权;yield from是生成器委托语法,仅转发迭代,不触发异步等待,二者语义与接口契约完全不同,不可互换。

python await 与 yield from 的区别

await 只能在 async 函数里用,yield from 不能直接替代它

很多人想用 yield from 模拟 await,结果报 SyntaxError: 'yield' inside async function 或运行时卡死。根本原因是:二者语义不同。await 是协程调度原语,依赖事件循环接管控制权;yield from 是生成器委托语法,只做迭代转发,不触发异步等待。

典型错误场景:把 async def 函数里一个 await asyncio.sleep(1) 换成 yield from asyncio.sleep(1) —— 直接语法报错,因为 asyncio.sleep() 返回的是 Future 对象,不是可迭代对象,yield from 根本无法消费它。

  • await 后面必须是 awaitable(coroutineFuture、实现了 __await__ 的对象)
  • yield from 后面必须是 iterator(或支持 __iter__ / __next__ 的对象)
  • 混用会导致类型错误或 TypeError: cannot 'yield from' a coroutine object

yield from 在 asyncio 里基本没用武之地

除非你手动写生成器驱动的协程调度器(比如 Python 3.4 以前的 @asyncio.coroutine + yield from 风格),否则在现代 Python(3.5+)中,yield fromasync/await 属于两套不兼容的异步机制。

常见误解是“yield from 能让协程暂停”,但它只是把子生成器的产出逐个 yield 出来,并不移交事件循环控制权。真正让出 CPU 的是 await + 事件循环的 awaitable 对象(如 asyncio.sleep()await reader.read(1024))。

立即学习Python免费学习笔记(深入)”;

VisionStory
VisionStory

AI视频、直播、视频播客

下载
  • Python 3.5 引入 async/await 后,@asyncio.coroutineyield from 已被标记为 deprecated
  • yield from 包裹 asyncio.sleep()awaitable 会抛 TypeError
  • 想调试协程执行流?别用 yield from 插桩,改用 asyncio.create_task() + 日志,或 asyncio.current_task()

await 的实际行为取决于对象的 __await__ 方法

await 不是魔法,它只是调用对象的 __await__ 方法并迭代其返回的 iterator。这个 iterator 每次 yield 一个 Awaitable,直到结束,事件循环才继续推进当前协程。

所以你能 await 一个自定义类,只要它实现 __await__ 并返回有效 iterator:

class MyAwaitable:
    def __await__(self):
        yield  # 让出一次控制权
        return "done"
<p>async def f():
result = await MyAwaitable()  # 合法</p>

yield from 完全不关心 __await__,它只认 __iter__。这也是为什么不能互换——接口契约完全不同。

  • await x 等价于 x.__await__().__next__()(简化理解)
  • yield from x 等价于 for i in x: yield i
  • 第三方库若返回 Futurecoroutine,只能 await,不能 yield from

迁移旧代码时最容易漏掉的兼容性陷阱

@asyncio.coroutine + yield from 改成 async/await 时,最常踩的坑不是语法,而是隐式状态泄漏:旧风格里生成器帧对象可能保留局部变量引用,导致内存不释放;新风格下协程对象生命周期更清晰,但如果你在 async def 里意外用了 yield(非 yield from),函数就变成生成器了,调用它不会返回协程对象,而是生成器对象——然后你 await 它,立刻报 TypeError: object XXX can't be used in 'await' expression

  • 检查所有 async def 函数体内是否混入了 yield(哪怕只有一行)
  • 旧代码里 yield from asyncio.wait(...) 必须改成 await asyncio.wait(...),且注意 asyncio.wait() 返回值结构变了(现在返回 (done, pending),不再是 generator)
  • pylintmypy 开启 await-never-in-async-def 类检查项,能提前发现 yield 混用

异步的本质不在关键字,在控制流移交时机。写错一个 yield,整个协程就降级成同步生成器,而且错误往往延迟到 await 那一刻才暴露。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1583

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

463

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2274

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

40

2026.01.19

function是什么
function是什么

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

494

2023.08.04

js函数function用法
js函数function用法

js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

166

2023.10.07

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

928

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

307

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

183

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 4.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号