You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Generator与Iterator对比:yield工作原理及内存差异疑问

解答

首先,你的猜想不完全准确:生成器确实是迭代器的一种,但并非“继承基础迭代器重写next”这么简单——Python的生成器是由解释器自动创建的特殊迭代器对象,而非基于用户自定义类的继承实现。

一、yield的工作原理

当你定义一个包含yield的函数时,Python解释器会把它标记为生成器函数。调用这个函数时,不会立即执行函数体代码,而是返回一个生成器对象。

每次调用next()(或通过for循环隐式调用)时,函数体才会执行,直到遇到yield语句:

  • 执行到yield时,返回yield后的值,同时暂停函数的执行状态(包括局部变量、当前执行位置等);
  • 下一次调用next()时,函数从暂停的位置继续执行,直到再次遇到yield或执行完函数体(此时抛出StopIteration)。

二、内存差异的核心原因

  1. 对象结构的本质区别

    • 自定义迭代器是你手动创建的类实例,它需要携带类本身的元数据(比如方法定义、继承链、类属性等),sys.getsizeof(CustomIterator)统计的就是类对象的内存,这部分本身就占用了大量空间;而生成器是Python内置的轻量级迭代器,没有自定义类的额外元数据开销。
    • 你的自定义迭代器实例还保存了__position和__collection两个实例属性,而生成器内部仅保存最必要的执行状态(比如当前迭代位置、函数上下文),且这些状态由解释器高效管理,内存占用远低于自定义类实例。
  2. 内存统计的不公平对比
    你在自定义迭代器的统计中加入了类对象的内存(sys.getsizeof(CustomIterator)),但生成器的统计里并没有包含生成器函数本身的内存——这部分是额外的、不必要的对比项。即使去掉类对象的内存,自定义迭代器实例的内存仍会比生成器对象大,因为生成器是解释器优化后的内置结构。

  3. 解释器层面的优化
    Python的生成器是专门为迭代场景设计的内置对象,经过了大量底层优化,内存占用被压缩到最小;而自定义迭代器类需要遵循Python通用的类对象模型,包含实例字典、类型指针等通用开销,这些都是生成器不需要的。

三、关于生成器与迭代器的关系

生成器本质上是迭代器的一种实现,它自动实现了__iter__和__next__方法:生成器对象的__iter__返回自身,__next__则对应yield的执行逻辑——但这是解释器自动为生成器生成的,并非用户手动继承重写。


内容的提问来源于stack exchange,提问作者Leo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 23:02:18