首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python意外StopIteration

Python意外StopIteration
EN

Stack Overflow用户
提问于 2014-08-03 07:55:41
回答 2查看 4.7K关注 0票数 2

这是我的密码

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-03 07:58:54

因为f只产生一个值,所以只能在它上调用next一次。

表达式(next(it, None))的右侧是在左手边之前计算的,因此会耗尽生成器。

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

票数 9
EN

Stack Overflow用户

发布于 2014-08-03 07:57:07

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

代码语言:javascript
复制
>>> 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函数一样被执行,并添加暂停。生成器上的next()不暂停代码,然后运行代码,直到执行下一个yield语句。然后,该语句再次暂停生成器。如果函数结束(返回),则引发StopIteration

f()生成器中,这意味着:

  1. 当您调用f()时,将创建一个新的生成器对象。功能体暂停。
  2. 你第一次打电话给next()。代码开始运行,创建一个A()实例并生成该实例。函数再次暂停。
  3. 你第二次打电话给next()。代码开始运行,到达函数的末尾,然后返回。StopIteration被提出。

如果您向f()添加了一个循环,或者仅仅添加了第二个yield行,那么您的代码可以工作:

代码语言:javascript
复制
def f():
    yield A()
    yield A()

代码语言:javascript
复制
def f():
    while True:
        yield A()
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25102733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档