设为首页 收藏本站
查看: 1314|回复: 0

[经验分享] Python yield 生成器

[复制链接]

尚未签到

发表于 2017-4-26 07:10:52 | 显示全部楼层 |阅读模式
yield:生成器

任何使用yield的函数都称之为生成器,如:

def count(n):
while n > 0:
yield n   #生成值:n
n -= 1
 
另外一种说法:生成器就是一个返回迭代器的函数,与普通函数的区别是生成器包含yield语句,更简单点理解生成器就是一个迭代器。
使用yield,可以让函数生成一个序列,该函数返回的对象类型是"generator",通过该对象连续调用next()方法返回序列值。

c = count(5)
c.next()
>>> 5
c.next()
>>>4
 
生成器函数只有在调用next()方法的时候才开始执行函数里面的语句,比如:

def count(n):
print "cunting"
while n > 0:
yield n   #生成值:n
n -= 1
 
在调用count函数时:c=count(5),并不会打印"counting"只有等到调用c.next()时才真正执行里面的语句。每次调用next()方法时,count函数会运行到语句yield n处为止,next()的返回值就是生成值n,再次调用next()方法时,函数继续执行yield之后的语句(熟悉Java的朋友肯定知道Thread.yield()方法,作用是暂停当前线程的运行,让其他线程执行),如:

def count(n):
print "cunting"
while n > 0:
print 'before yield'
yield n   #生成值:n
n -= 1
print 'after yield'
 
上述代码在第一次调用next方法时,并不会打印"after yield"。如果一直调用next方法,当执行到没有可迭代的值后,程序就会报错:




Traceback (most recent call last): File "", line 1, in StopIteration




所以一般不会手动的调用next方法,而使用for循环:

for i in count(5):
print i,
 
实例: 用yield生成器模拟Linux中命令:tail -f | grep python 用于查找监控日志文件中出现有python字样的行。

import time
def tail(f):
f.seek(0,2)#移动到文件EOF,参考:[seek](http://docs.python.org/2/library/stdtypes.html?highlight=file#file.seek)
while True:
line = f.readline()  #读取文件中新的文本行
if not line:
time.sleep(0.1)
continue
yield line
def grep(lines,searchtext):
for line in lines:
if searchtext in line:
yield line
 
调用:

flog = tail(open('warn.log'))
pylines = grep(flog,'python')
for line in pylines:
print line,
 
用yield实现斐波那契数列:

def fibonacci():
a=b=1
yield a
yield b
while True:
a,b = b,a+b
yield b
 
调用:

for num in fibonacci():
if num > 100:
break
print num,
 
yield中return的作用:
作为生成器,因为每次迭代就会返回一个值,所以不能显示的在生成器函数中return 某个值,包括None值也不行,否则会抛出“SyntaxError”的异常,但是在函数中可以出现单独的return,表示结束该语句。
通过固定长度的缓冲区不断读文件,防止一次性读取出现内存溢出的例子:


def read_file(path):
size = 1024
with open(path,'r') as f:
while True:
block = f.read(SIZE)
if block:
yield block
else:
return
 
如果是在函数中return 具体某个值,就直接抛异常了

>>> def test_return():
...      yield 4
...      return 0
...
File "<stdin>", line 3
SyntaxError: 'return' with argument inside generator
 
与yield有关的一个很重要的概念叫**协程**,下次好好研究研究。
参考:
http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html
http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/
《Python 参考手册》

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-369222-1-1.html 上篇帖子: [转]python迭代,yield使用 下篇帖子: (转)关于Python中的yield
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表