在 Python 2 中,函数定义中 return 与 yield 一起出现错误。但是对于 Python 3.3 中的这段代码
def f():
return 3
yield 2
x = f()
print(x.__next__())
在有收益的函数中使用 return 没有错误。但是,当__next__
调用该函数时,会抛出异常 StopIteration。为什么不只是返回值3
?这个回报是否被忽略了?
在 Python 2 中,函数定义中 return 与 yield 一起出现错误。但是对于 Python 3.3 中的这段代码
def f():
return 3
yield 2
x = f()
print(x.__next__())
在有收益的函数中使用 return 没有错误。但是,当__next__
调用该函数时,会抛出异常 StopIteration。为什么不只是返回值3
?这个回报是否被忽略了?
这是 Python 3.3 中的一个新功能(正如注释所述,它甚至在 3.2 中都不起作用)。很像return
in a generator 早就等价于raise StopIteration()
,return <something>
in a generator 现在等价于raise StopIteration(<something>)
。因此,您看到的异常应该打印为StopIteration: 3
,并且可以通过value
异常对象上的属性访问该值。如果生成器被委托使用(也是新的)yield from
语法,它就是结果。有关详细信息,请参阅PEP 380。
def f():
return 1
yield 2
def g():
x = yield from f()
print(x)
# g is still a generator so we need to iterate to run it:
for _ in g():
pass
这打印1
,但不是2
。
返回值不会被忽略,但生成器只产生值,areturn
只是结束生成器,在这种情况下提前。在这种情况下,推进生成器永远不会到达yield
语句。
每当迭代器到达要产生的值的“结束”时,StopIteration
必须引发 a。发电机也不例外。然而,从 Python 3.3 开始,任何return
表达式都会成为异常的值:
>>> def gen():
... return 3
... yield 2
...
>>> try:
... next(gen())
... except StopIteration as ex:
... e = ex
...
>>> e
StopIteration(3,)
>>> e.value
3
使用该next()
函数来推进迭代器,而不是.__next__()
直接调用:
print(next(x))