如何让Python自定义range类具备内置range的可重置复用特性?
实现可复用的自定义Range(与Python内置range行为一致)
你用生成器函数实现的exampleCustomRange仅能被遍历一次,第二次遍历时会返回空序列,这和Python内置range的可复用特性不符。
问题复现代码
def exampleCustomRange(stopExclusive): for i in range(stopExclusive): yield i # REPL 测试 builtinRange = range(3) [x for x in builtinRange] # 输出: [0, 1, 2] [x for x in builtinRange] # 再次遍历仍输出: [0, 1, 2],支持复用 customRange = exampleCustomRange(3) [x for x in customRange] # 输出: [0, 1, 2] [x for x in customRange] # 第二次遍历输出: [],无法复用
原因说明
生成器函数返回的是一次性迭代器,迭代器被耗尽后就无法生成新值。而内置range是一个可迭代对象类,每次对它进行遍历操作时,都会创建一个新的迭代器实例,因此能重复遍历。
解决方案
方法1:自定义类实现__iter__方法
这种方式最贴近内置range的使用体验,通过类封装状态,每次迭代时生成新的生成器:
class CustomRange: def __init__(self, stopExclusive): self.stop = stopExclusive def __iter__(self): # 每次遍历都生成新的生成器 for i in range(self.stop): yield i
测试效果:
custom_range = CustomRange(3) [x for x in custom_range] # 输出: [0, 1, 2] [x for x in custom_range] # 输出: [0, 1, 2],成功复用
方法2:返回生成器工厂函数
如果不想使用类,可以让函数返回一个生成器工厂,每次调用工厂函数都会得到新的生成器:
def exampleCustomRange(stopExclusive): def generator(): for i in range(stopExclusive): yield i return generator
使用方式:
custom_range_factory = exampleCustomRange(3) [x for x in custom_range_factory()] # 输出: [0, 1, 2] [x for x in custom_range_factory()] # 输出: [0, 1, 2]
内容的提问来源于stack exchange,提问作者user2183336
相关产品推荐
相关产品推荐

