ozg*_*gur 3 python iteration yield generator
我有一个名为x的函数,它生成一个这样的生成器:
a = 5
def x():
global a
if a == 3:
raise Exception("Stop")
a = a - 1
yield a
Run Code Online (Sandbox Code Playgroud)
然后在python shell中我调用这个函数:
>>> print x().next()
>>> 4
>>> print x().next()
>>> 3
>>> print x().next()
>>> <python-input-112-f3c02bba26c8> in x()
2 global a
3 if a == 3:
----> 4 raise Exception
5 a = a - 1
6 yield a
Exception:
Run Code Online (Sandbox Code Playgroud)
但是,当我调用该函数并将其分配给变量时,它的行为有所不同:
>>> a = 5
>>> b = x()
>>> print b.next()
>>> 4
>>> print b.next()
>>> ----> 1 b.next()
StopIteration:
Run Code Online (Sandbox Code Playgroud)
这怎么可能呢?它不应该打印3并在下一次迭代中提高StopIteration吗?
PS:我知道当我第一次调用函数时,身体不会运行,只需生成一个生成器.我不明白的一点是,如果我调用并将其分配给变量会发生什么变化?
Mar*_*ers 13
在您的第一个示例中,您每次都在创建一个新生成器:
x().next()
Run Code Online (Sandbox Code Playgroud)
这从顶部开始生成器,所以第一个语句.何时a == 3引发异常,否则生成器只会产生并暂停.
当你稍后分配你的生成器,全局a开始时5,代码然后从它离开的地方继续,直到它结束或遇到另一个yield语句,然后结束.当发电机功能结束时,它会升起StopIteration.
让我们把它分解为几步:
a = 5.您创建新的生成器并调用.next()它.执行以下代码:
global a
if a == 3: # False
raise Exception("Stop")
a = a - 1 # a is now 4
yield a
Run Code Online (Sandbox Code Playgroud)
生成器在最后一行暂停,并被4放弃.
您创建一个新的生成器并调用.next()它.a是4在开始:
global a
if a == 3: # False
raise Exception("Stop")
a = a - 1 # a is now 3
yield a
Run Code Online (Sandbox Code Playgroud)
生成器在最后一行暂停,并被3放弃.
您创建一个新的生成器并调用.next()它.a是3在开始:
global a
if a == 3: # True
raise Exception("Stop")
Run Code Online (Sandbox Code Playgroud)
提出了一个例外.
你a = 5再次设置.
您创建一个新的生成器,存储引用b并调用.next()它.执行以下代码:
global a
if a == 3: # False
raise Exception("Stop")
a = a - 1 # a is now 4
yield a
Run Code Online (Sandbox Code Playgroud)
生成器在最后一行暂停,并被4放弃.
您.next() 再次调用由相同的现有生成器引用b.代码将在暂停点恢复.
该函数在该点没有更多代码,并返回.StopIteration被提出来了.
如果您使用循环代替,您会看到更好的差异:
>>> def looping(stop):
... for i in looping(stop):
... yield i
...
>>> looping(3).next()
0
>>> looping(3).next()
0
Run Code Online (Sandbox Code Playgroud)
请注意每次创建新生成器时,循环从头开始.然而,存储引用,你会发现它继续:
>>> stored = looping(3)
>>> stored.next()
0
>>> stored.next()
1
>>> stored.next()
2
>>> stored.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Run Code Online (Sandbox Code Playgroud)
在循环期间,每次yield执行表达式时,代码都会暂停 ; 调用.next()继续前一次离开的功能.
的StopIteration例外是完全正常的; 它是生成器如何沟通它们已完成的.一个for循环查找该异常来结束循环:
>>> for i in looping(3):
... print i
...
0
1
2
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
337 次 |
| 最近记录: |