Python中迭代器内的变量是如何保存的?
有下面一段代码,分别打印 1 1 2 3 5 和 0 0 0 0 0,请问后面一个迭代器为什么不会打印 0 1 2 3 4 ?
class Fib(object):
def __init__(self):
self.prev = 0
self.curr = 1
def next(self):
value = self.curr
self.curr += self.prev
self.prev = value
return value
def __iter__(self):
return self
class T(object):
def iter(self):
return self
def next(self):
for i in range(5):
return i
f = Fib()
t = T()
print next(f)
print next(f)
print next(f)
print next(f)
print next(f)
print next(t)
print next(t)
print next(t)
print next(t)
print next(t)
Python中迭代器内的变量是如何保存的?
因为已经 return 了,后面 i=1,2,3,4 根本不会运行
在Python里,迭代器内部变量的保存方式其实挺直接的,主要看这个迭代器是怎么实现的。
最常见的就是用生成器函数(带 yield 的函数)。当函数执行到 yield 时,它会暂停,并把所有局部变量、指令指针这些状态都保存在一个生成器对象里。下次调用 next(),它就从上次暂停的地方接着跑,变量值当然也还在。
给你看个例子就明白了:
def my_counter(start):
print("生成器初始化")
count = start
while True:
print(f"yield前,count = {count}")
yield count
count += 1
print(f"yield后,count = {count}")
# 创建生成器对象
counter = my_counter(5)
# 第一次next
print("第一次next:")
val1 = next(counter) # 输出: 生成器初始化 \n yield前,count = 5
print(f"拿到值: {val1}\n")
# 第二次next
print("第二次next:")
val2 = next(counter) # 输出: yield后,count = 6 \n yield前,count = 6
print(f"拿到值: {val2}\n")
# 第三次next
print("第三次next:")
val3 = next(counter) # 输出: yield后,count = 7 \n yield前,count = 7
print(f"拿到值: {val3}")
运行这个,你会看到 count 这个变量在每次 yield 暂停时都被“冻住”了,下次恢复时值完全保留。它和闭包有点像,但机制不同:闭包是靠外层函数的栈帧,而生成器是把自己的整个栈帧(包括局部变量)保存下来。
如果是自己写迭代器类(实现 __iter__ 和 __next__),那更简单:变量就是作为实例属性(self.xxx)存着的,每次 __next__ 调用都能访问到。
所以核心就一句话:迭代器的状态(包括变量)保存在它的执行帧或对象属性里,靠这个实现暂停和恢复。
yield 才是给迭代器用的
查一查 magic method
Next 调用的是 next 这个方法
但是第一个 Fib 的实例就运行了。
迭代器只要求有 next 和__iter__,yield 是给生成器函数用的。
__next__是 Python 3 的方法,Python 2 的叫 next。
#1 说的对,每次你用 next(t) 的時候,就調用一次 t.next()。你可以在[這裏]( http://pythontutor.com/visualize.html) 寫下你的代碼,可視化你的執行步驟。
for i in range(5):
return i
楼主你再看看?
Fib 的話,記錄了當前迭代的狀態,所以完全沒問題
迭代器只要求有 next 和__iter__,yield 是给生成器函数用的。
一般也是用 yield 实现 next,用 return 不是不行,多麻烦啊

