这是我的代码
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
。
答案 0 :(得分:8)
由于f
只生成一个值,因此您只能在其上调用next
一次。
表达式的右侧(next(it, None)
)在左侧之前进行评估,从而耗尽发电机。
然后在左侧调用next(it).a
会引发StopIteration
。
答案 1 :(得分:3)
您的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先执行右侧表达式 first ,然后再确定将分配给的内容。因此首先调用next(it, None)
,分配的next(it).a
称为 second 。
f()
函数的主体与任何其他Python函数一样执行,并添加暂停。生成器上的next()
取消暂停代码,然后代码运行直到执行下一个yield
语句。该声明然后再次暂停发电机。如果函数结束(返回),则会引发StopIteration
。
在f()
生成器中,这意味着:
f()
时,会创建一个新的生成器对象。功能正文已暂停。next()
。代码开始运行,创建A()
的实例并生成该实例。该功能再次暂停。next()
。代码开始运行,到达函数的末尾,然后返回。 StopIteration
被提出。如果您向f()
添加循环,或只是添加第二个 yield
行,则代码可以正常运行:
def f():
yield A()
yield A()
或
def f():
while True:
yield A()