可以先看下这篇文章:http://www.cnblogs.com/jiangtu/articles/6662043.html
原篇是转载的:http://www.python-tab.com/html/2015/pythonhexinbiancheng_0415/946.html (去掉连字符 - ,博客园显示违禁字。。)
之前对 yield表达式 了解的也不清楚,只知道包含 yield表达式 的函数 会被编译成迭代器,如以下代码:
def g(n): for i in range(n): yield i **2 # 打印输出 for i in g(5): print i # 输出 0, 1, 4, 9, 16
函数 g(n) 包含 yield表达式,所以 g(n) 被编译成迭代器。
插一句:范围都是左开右闭 类似:[..) (加强记忆 - -.)
但是之后碰到过,一个函数内有多个 yield表达式,或者 yield表达式 前有 return 语句,或者 yiled return 语句,又代表什么呢?(其实g(n)中就有多个 yield表达式的,可是当初我没想到。。)
通过如下代码,可以了解些其过程:
1 # coding:utf-8 2 def g(): 3 print "第一次yield之前" 4 yield "第一次yield" 5 print "第二次yield之前" 6 d = yield "第二次yield" 7 print d 8 print "函数结尾,之后没有yield"
输出结果为:
1 >>> import test 2 >>> fun = test.g() 3 >>> fun 4 <generator object g at 0x7f422a6c3460> 5 >>> fun.next() 6 第一次yield之前 7 'xe7xacxacxe4xb8x80xe6xacxa1yield' 8 >>> fun.send("None") 9 第二次yield之前 10 'xe7xacxacxe4xbax8cxe6xacxa1yield' 11 >>> fun.send("see send function") 12 see send function 13 函数结尾,之后没有yield 14 Traceback (most recent call last): 15 File "<stdin>", line 1, in <module> 16 StopIteration
可以看出,
- 函数确实被编译成迭代器(line 3~4),
- 返回迭代器的下一个元素时,即 fun.next() ,
- 会执行 迭代器当前位置到下一个yield中间的代码段(line5~7),
- 返回值为下一个yield表达式的值(line 7)。
总结下,就是:包含yield表达式的函数会被编译成迭代器返回,并且,对此迭代器进行迭代时,会将 yield表达式间的代码执行,并将yield表达式后的值作为返回值返回。First next是函数开始到第一个yield表达式,如果末尾没有yield表达式,最后一次迭代会抛异常(StopIteration)。(for循环会检测异常且自动调用next() )
至于 yield return ,直接报错。。但是我怎么记得在哪看到过呢?
其次,可以通过 fun.send(msg) 可以msg赋值给yield表达式,即 "yield '第二次yield' ",所以d的值会是msg。
即:fun.next() == fun.send(None) 详细可以看开头转载的那篇文章
最后,yield表达式在一定程度上实现了协程,参见连接:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868328689835ecd883d910145dfa8227b539725e5ed000