在Python 3.3中返回生成器和yield
在Python 2中,当函数定义中的return与yield一起出现错误。 但在Python 3.3中的这个代码
def f(): return 3 yield 2 x = f() print(x.__next__())
没有任何错误,返回function与产量使用。 但是,当函数__next__
被调用,则会引发exceptionStopIteration。 为什么不只是返回值3
? 这个回报不知何故被忽略?
这是Python 3.3中的一个新特性(作为注释,它甚至在3.2中不起作用)。 就像在生成器中return
一样,一直等于raise StopIteration()
, return <something>
在生成器中return <something>
现在等价于raise StopIteration(<something>)
。 出于这个原因,你看到的exception应该打印为StopIteration: 3
,并且该值可以通过exception对象的属性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
。
返回值不被忽略,但是发生器只产生值, return
只是结束发生器,在这种情况下是早期的。 在这种情况下推进发电机永远不会达到yield
声明。
每当迭代器到达要产生的值的“结束”时,都必须提出StopIteration
。 发电机也不例外。 但是,从Python 3.3开始,任何return
expression式都将成为exception的值:
>>> 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))