Python 3:哪些迭代器(iterator)不属于生成器(generator)?
Python 迭代器与生成器的区别及核心判定规则
基础定义
迭代器的判定标准
符合迭代器协议的对象就是迭代器,仅需满足两个条件:
- 实现了
__iter__方法,调用时返回对象自身 - 实现了
__next__方法,每次调用返回下一个元素,无剩余元素时抛出StopIteration异常
所有迭代器都可以用next()函数直接取值。
生成器的判定标准
生成器是迭代器的特殊子类,是Python提供的简化创建迭代器的语法实现,必须满足两个前提:
- 符合迭代器的所有要求(天然满足,Python会自动为生成器实现
__iter__和__next__方法) - 只能通过两种方式创建:
- 内部使用了
yield关键字的函数,调用后返回的对象 - 生成器表达式,也就是
(i**2 for i in range(1,5))这类写法,属于Python语法糖,底层还是基于yield逻辑实现
除了迭代器的基础能力外,生成器还有专属方法:send()、throw()、close(),普通迭代器不具备这些方法。
- 内部使用了
常见问题解答
属于迭代器但不属于生成器的示例
最典型的就是你提到的iter([1,2,3]),它是列表迭代器,属于迭代器但不是生成器,可以用代码直接验证:
from collections.abc import Iterator, Generator list_iter = iter([1,2,3]) # 验证属于迭代器 print(isinstance(list_iter, Iterator)) # 输出 True # 验证不属于生成器 print(isinstance(list_iter, Generator)) # 输出 False # 验证没有生成器专属方法 print(hasattr(list_iter, 'send')) # 输出 False
除此之外,调用open()返回的文件句柄、map()/filter()的返回对象都属于迭代器,但不是生成器。
有__next__方法的对象是不是就是生成器?
不是。__next__只是迭代器的判定条件之一,生成器有更严格的判定规则,普通自定义迭代器、内置容器的迭代器都有__next__方法,但都不属于生成器。
生成器表达式没有yield为什么属于生成器?
生成器表达式是Python预设的语法糖,编译器处理时会自动将其转换为yield实现的逻辑,和带yield的生成器函数底层实现完全一致,你可以验证它的类型和属性:
gen_exp = (i**2 for i in range(1,5)) print(type(gen_exp)) # 输出 <class 'generator'> print(hasattr(gen_exp, 'send')) # 输出 True
iter([1,2,3])不是生成器的依据
符合Python官方对Generator类型的定义:只有通过生成器函数或者生成器表达式创建的、同时实现了迭代器协议和生成器专属接口的对象才属于生成器。iter([1,2,3])返回的是列表迭代器对象,没有实现生成器的专属接口,也不是通过生成器的两种创建方式得到的,因此不属于生成器。
内容的提问来源于stack exchange,提问作者Timur
相关产品推荐
相关产品推荐

