讲师中心 微信公众号
AI工具推荐 视频效率加速

Python 可迭代对象设计的工程思维

轻婷同学_5837

轻婷同学_5837

发布时间:2026-02-18 10:38:03

|

450人浏览过

|

来源于php中文网

原创

__iter__ 必须返回新迭代器而非 self,因可迭代对象与迭代器职责分离:前者负责生成,后者管理状态;否则多次遍历失败,违反PEP 234契约。

python 可迭代对象设计的工程思维

为什么 __iter__ 返回迭代器,而不是直接返回 self

因为可迭代对象(Iterable)和迭代器(Iterator)在语义和生命周期上必须分离。常见错误是让类同时实现 __iter__ 和 __next__ 并在 __iter__ 里返回 self,这会导致多次遍历失败——比如在 for 循环、list()、sum() 中重复使用同一个对象时,第二次调用就直接空了。

正确做法是:每次调用 __iter__ 都新建一个独立的迭代器实例。这个迭代器内部持有当前状态(如索引、游标),而可迭代对象本身只负责“生成”它。

  • 适用场景:range、dict.keys()、自定义数据容器(如树、链表)
  • 性能影响:新建对象开销极小,远小于状态错乱带来的逻辑 bug
  • 兼容性:符合 PEP 234,所有标准库函数(如 itertools.chain)都依赖这一契约

StopIteration 该由谁抛、什么时候抛

只能由迭代器的 __next__ 方法抛,且仅在“真的没有下一个元素”时抛。不能靠计数预判,也不能在初始化或 __iter__ 里抛。

常见错误包括:在 __next__ 开头就检查 if self.index >= len(self.data) 然后抛,但没处理空数据或边界变化;或者误把 IndexError 当 StopIteration 捕获并吞掉,导致无限循环。

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

macOS UI 自动化技能包 —— 用 Python 控制你的 Mac
macOS UI 自动化技能包 —— 用 Python 控制你的 Mac

让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限

下载
  • 安全写法:在取值后立即判断是否越界,再决定返回还是抛 StopIteration
  • 不要在生成器函数里手动 raise StopIteration —— return 就够了,否则会触发 RuntimeWarning
  • 协程或异步迭代器(__aiter__/__anext__)中,对应抛的是 StopAsyncIteration

如何让自定义类支持 in、len() 和解包而不重复实现

支持 in 查找靠 __contains__,支持 len() 靠 __len__,支持解包(如 a, b = obj)靠 __iter__。三者互不替代,也不能靠其中一个自动推导另一个。

典型坑是:只实现了 __iter__ 就以为 in 会自动变快——其实默认回退到逐个 __next__ 对比,时间复杂度 O(n);而自己写 __contains__ 可以用哈希、二分或索引优化到 O(1) 或 O(log n)。

  • __len__ 必须返回非负整数,返回负数会引发 ValueError
  • 解包要求对象可迭代且长度明确(否则报 ValueError: not enough values to unpack)
  • 如果底层数据支持快速查找(如 set 或带索引的 dict),别省那几行代码,直接实现 __contains__

用生成器函数代替手写迭代器类真的更“工程”吗

绝大多数情况下是的,但前提是逻辑不依赖外部状态重入或并发访问。生成器函数(含 yield)本质是语法糖,Python 自动帮你管理了 __iter__ 和 __next__,还内置了状态挂起/恢复机制。

容易被忽略的点是:生成器对象不可重用。调用一次 list(gen()) 后,再次传给 sum(gen()) 就是空的——因为它不是可迭代对象,而是迭代器。所以若需要多次遍历,得包装一层类,或每次调用生成器函数重新创建。

  • 适合场景:一次性数据流(日志行、API 分页结果)、简单变换(map 类逻辑)
  • 不适合场景:需暂停/恢复多个独立遍历(如双指针算法)、需共享内部缓存(如预加载下一页)
  • 调试难点:生成器内部变量无法在暂停时 inspect,不如类属性直观

真正难的不是写对,而是想清楚“这个对象的生命周期归谁管”——是调用方每次要新拿一个,还是它自己能反复交出新迭代器。这点一旦错,下游所有 for、list()、itertools 组合都会静默失效。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

650

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

343

2025.11.16

golang map原理
golang map原理

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

533

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

303

2025.11.27

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

6516

2023.08.14

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

100

2026.10.28

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

60

2026.10.28

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

220

2026.10.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn