标签:
yield有点类似于continue和return的结合, 代码的运行的过程方式都是一样的, 执行完一行之后运行下一行.
在continue里面(请查看注意事项里面的2说明), 当执行的代码遇到continue的时候, 就不会再执行后续的语句, 而是跳到循环的头部位置进行下一次循环.
在yield里面(请查看注意事项里面的1说明), 当执行的代码遇到yield的时候, 就不会再执行后续的语句, 而是跳出函数, 并返回结果.
[root@localhost ~]# vim test_yield.py #!/bin/env python # -.- coding:utf-8 -.- def hello(n): print ‘yield之前‘ n += 1 yield n print ‘yield之后‘ n *= 2 print n s = hello(100) print ‘运行第一个next‘ s.next()
# 运行结果
[root@localhost ~]# python test_yield.py 运行第一个next yield之前 # 这个是输出结果.
总结: 通过这段代码可以看出来, 当执行的代码遇到yield的时候, 就不会再执行后续的语句, 而是跳出函数, 并返回结果.
[root@localhost ~]# vim test_yield.py #!/bin/env python # -.- coding:utf-8 -.- def hello(n): print ‘yield之前‘ n += 1 yield n print ‘yield之后‘ n *= 2 print n s = hello(100) print ‘运行第一个next‘ s.next() print ‘\n\n运行第二个next‘ # 增加了这行代码 s.next() # 增加了这行代码
# 运行结果
[root@localhost ~]# python test_yield.py 运行第一个next yield之前 运行第二个next yield之后 202 Traceback (most recent call last): File "test_yield.py", line 34, in <module> s.next() StopIteration
总结: 通过这段代码可以看出来, 当第二次运行next的时候, 其实是先运行第一次阻断后面的内容, 然后才报错, 这个报错是因为没有next了.
#!/bin/env python # -.- coding:utf-8 -.- def get_time(): from datetime import datetime return datetime.now() def hello(n): for i in xrange(n): print ‘yield之前‘, print get_time() yield n print ‘yield之后‘, print get_time() s = hello(5) print ‘运行第一个next‘ s.next() print ‘\n\n运行第二个next‘ s.next() print ‘\n\n运行第三次next‘ s.next() print ‘\n\n运行第四次next‘ s.next() print ‘\n\n运行第五次next‘ s.next() print ‘\n\n运行第六次next‘ s.next()
# 运行结果
[root@localhost ~]# python test_yield.py 运行第一个next yield之前 2015-11-10 01:58:31.753858 运行第二个next yield之后 2015-11-10 01:58:31.753908 yield之前 2015-11-10 01:58:31.753941 运行第三次next yield之后 2015-11-10 01:58:31.753952 yield之前 2015-11-10 01:58:31.753957 运行第四次next yield之后 2015-11-10 01:58:31.753965 yield之前 2015-11-10 01:58:31.753970 运行第五次next yield之后 2015-11-10 01:58:31.753977 yield之前 2015-11-10 01:58:31.753982 运行第六次next yield之后 2015-11-10 01:58:31.753989 Traceback (most recent call last): File "test_yield.py", line 67, in <module> s.next() StopIteration
总结: 通过上面这三个代码应该就已经大概知道yield是什么东西, 也知道它是怎么运作的了, 但是它老是报StopIteration这个错误.
[root@localhost ~]# vim test_yield.py #!/bin/env python # -.- coding:utf-8 -.- def get_time(): from datetime import datetime return datetime.now() def hello(n): for i in xrange(n): print ‘yield之前‘, print get_time() yield n print ‘yield之后‘, print get_time() counter = 1 for i in hello(5): print ‘\n\n运行第%s个next‘ % counter counter += 1
# 运行结果
[root@localhost ~]# python test_yield.py yield之前 2015-11-10 02:03:50.148205 运行第1个next yield之后 2015-11-10 02:03:50.148256 yield之前 2015-11-10 02:03:50.148265 运行第2个next yield之后 2015-11-10 02:03:50.148274 yield之前 2015-11-10 02:03:50.148279 运行第3个next yield之后 2015-11-10 02:03:50.148286 yield之前 2015-11-10 02:03:50.148291 运行第4个next yield之后 2015-11-10 02:03:50.148299 yield之前 2015-11-10 02:03:50.148304 运行第5个next yield之后 2015-11-10 02:03:50.148311
[root@localhost ~]# vim multi-para_yield.py #!/bin/env python # -.- coding:utf-8 -.- def hello(n): for i in xrange(n): print ‘yield之前‘ new_value = yield i print ‘yield之后‘ print ‘new_value is:‘, new_value, i s = hello(3) print ‘\n\n第一次next‘ s.next() print ‘\n\n第二次next‘ s.next() print ‘\n\n第三次next(其实是send)‘ s.send(‘hello world!‘)
# 运行结果
[root@localhost ~]# python multi-para_yield.py 第一次next yield之前 第二次next yield之后 new_value is: None 0 yield之前 第三次next(其实是send) yield之后 new_value is: hello world! 1 # 重点在这里, 会发现传参和自身变量截然不同, 这应该是yield传参的固有写法. yield之前
1. yield只能写在函数里面, 不能写在函数外面.
2. continue只能运行在循环语句中.
3. 无法使用try来规避调用next时报的StopIteration错误.
4. yield对象所有属性:
[‘__class__‘, ‘__delattr__‘, ‘__doc__‘, ‘__format__‘, ‘__getattribute__‘, ‘__hash__‘, ‘__init__‘, ‘__iter__‘,
‘__name__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘, ‘__str__‘,
‘__subclasshook__‘, ‘close‘, ‘gi_code‘, ‘gi_frame‘, ‘gi_running‘, ‘next‘, ‘send‘, ‘throw‘]
标签:
原文地址:http://my.oschina.net/u/2452965/blog/528548