如何在不重新实例化的前提下重置无限生成器中的变量?
如何重置已迭代的生成器而不重新实例化?
这个问题我之前也碰到过——不想每次都重新创建生成器实例,又需要把内部的状态重置回初始值,对吧?给你几个实用的解决方案,按需选就行:
方案1:用类封装生成器状态,自带重置方法
把生成器的状态(也就是你的i变量)放到类的实例属性里,再专门写一个reset方法来重置状态。这种方式最直观,状态管理也清晰:
class ResettableIndexGenerator: def __init__(self): self.i = 0 # 把状态存在实例属性里 def __iter__(self): return self def __next__(self): result = self.i ** 2 self.i += 1 return result def reset(self): self.i = 0 # 重置状态的方法
使用方式:
my_gen = ResettableIndexGenerator() # 第一次迭代100次 for _ in range(100): print(next(my_gen)) # 输出0,1,4,...9801 # 重置生成器 my_gen.reset() # 再迭代100次,又从0开始输出 for _ in range(100): print(next(my_gen))
这个方案特别适合需要多次重置、或者需要同时管理多个生成器实例的场景,可读性和维护性都很强。
方案2:闭包+可变对象实现轻量重置
如果不想写类,可以用闭包把状态封装起来,用可变对象(比如列表)来保存i(因为整数是不可变类型,闭包里没法直接修改),同时返回一个重置函数:
def make_resettable_generator(): i = [0] # 用列表存状态,方便闭包修改 def generator(): while True: yield i[0] ** 2 i[0] += 1 def reset(): i[0] = 0 # 重置状态的函数 # 返回生成器对象和重置函数 return generator(), reset
使用方式:
my_gen, reset_gen = make_resettable_generator() # 第一次迭代 for _ in range(100): print(next(my_gen)) # 调用重置函数 reset_gen() # 再次迭代,回到初始状态 for _ in range(100): print(next(my_gen))
这个方案比较轻量,不用定义类,适合简单场景下快速实现需求。
方案3:通过生成器的send()方法发送重置信号
利用生成器的send()特性,让生成器接收外部发送的信号,当收到特定信号时重置内部状态。这种方式不用改动太多原生成器的结构:
def index_generator(): i = 0 while True: # 接收外部发送的信号,默认是None received = yield i ** 2 if received == 'reset': i = 0 continue # 跳过i自增,直接进入下一轮循环 i += 1
使用方式:
my_gen = index_generator() # 第一次迭代100次 for _ in range(100): print(next(my_gen)) # 发送重置信号给生成器 my_gen.send('reset') # 再迭代100次,从0开始输出 for _ in range(100): print(next(my_gen))
注意:第一次调用必须用next()启动生成器,之后才能用send()发送信号;而且这个方式还支持在迭代过程中随时重置,灵活性很高。
内容的提问来源于stack exchange,提问作者mr.robot
相关产品推荐
相关产品推荐

