繁体   English   中英

Python意外的StopIteration

[英]Python unexpected StopIteration

这是我的代码

class A:
    pass

def f():
    yield A()

def g():
    it = f()
    next(it).a = next(it, None)

g()

产生StopIteration错误,此错误由next(it).a = next(it, None) 为什么?

该文档说,如果提供了默认值,则next函数不会引发StopIteration ,我希望它可以从生成器( A实例)获得第一项并将a属性设置为None

由于f仅产生一个值,你只能叫next的一次。

表达式的右手边( next(it, None) )在左手边之前求值,从而耗尽了生成器。

然后在左侧调用next(it).a将引发StopIteration

您的f()生成器函数仅产生一个值。 之后,它已耗尽并引发StopIteration

>>> class A:
...     pass
... 
>>> def f():
...     yield A()
... 
>>> generator = f()
>>> generator
<generator object f at 0x10be771f8>
>>> next(generator)
<__main__.A object at 0x10be76f60>
>>> next(generator)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

这是因为f() 没有循环可产生不止一次的结果,生成器函数本身并不会循环,只是因为您可以循环中使用它。

请注意,分配,Python的首先执行右手边的表达,搞清楚什么把它分配了。 所以, next(it, None)首先被调用,在next(it).a的分配称为第二

f()函数的主体与其他任何Python函数一样执行,除了增加了pause 生成器上的next()取消暂停代码,然后代码将运行直到执行下一个yield语句。 该语句然后再次暂停生成器。 如果该函数结束 (返回),则会引发StopIteration

在您的f()生成器中意味着:

  1. 当您调用f()将创建一个新的生成器对象。 功能主体已暂停。
  2. 您第一次调用next() 该代码开始运行,创建A()的实例并产生该实例。 该功能再次暂停。
  3. 您第二次调用next() 代码开始运行,到达函数结尾,然后返回。 StopIteration被引发。

如果将循环添加到f() ,或仅添加第二条 yield线,则代码可以正常工作:

def f():
    yield A()
    yield A()

要么

def f():
    while True:
        yield A()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM