yield是产出的意思,含yield的fab构成了一个生成器函数,向调用方发射值,函数执行到yield的地方就卡在那里,把yield右边的表达式的值发射回调用方,同时还保留了现场,下次还能回来,从yield左边接受值,接着往下走。生成器函数作为函数也是有返回值的,不要把刚才yield的值和return的返回值搞混!返回值跟普通函数是一样的,用return返回,你的fab函数有一个默认的隐藏返回值,就是在while跳出之后啥也没有了,按python的规矩就是return None,但这个返回值的获取跟普通函数不一样。不断next将生成器耗尽之后,就是不再yield东西了,在你的例子里就是跳出循环体,这个返回值None就要登台了,但此时生成器会抛出StopIteration异常,把返回值None做进异常里,你需要在外面处理这个异常才能拿到这个返回值。你的例子里三次next之后,再来一次next就会看到StopIteration,但这个None一般不打印出来,所以你感觉不到。你要是在fab结尾加个return XXXX,就能看到StopIteration异常里XXXX的值了。不断next是驱动生成器工作的低级方法,可以暴露工作的细节。for是驱动生成器的高级方法,把不断next的细节隐藏起来了,同时会处理最后的StopIteration异常,让你感觉不到这个过程的存在。
别在网上看各种乱七八糟的国内博客,花钱买本流畅的python,里面花了一个章节的篇幅介绍,包括把返回值藏在异常里返回都举了应用例子。
【 在 HYNOS 的大作中提到: 】
: yield 给了之后就没了吧?
: 所以下面这段代码的第二次next(generator)才会输出None?但是网上解释是:
: “调用第 2 个 next(generator) 的时候,生成器恢复执行,由于使用 next() 来调用
: ...................
--
FROM 219.142.144.*