在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开始,任何returnexpression式都将成为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))