最近在学习Python的时候看到yield的相关语法,感受很独特,相比其余如C/C++的语法比较有意思,因而在看完资料相关章节作一个总结。dom
yield 是一个相似于 return的语法,可是对于return 而言,在其执行以后,意味着将数据返回给调用者,子程序结束,可是yield却不同,它可以继续执行,直到下一个yield 转交执行权,以后又能够进入继续执行,周而复始,直到抛出异常。函数
for in range()是一个简单有用的循环,以前的学习知道range()返回的是一个对象,有惰性求值的特色,下面是一个利用yield简单模拟range()函数的特色学习
def xrange(m): n=m while(n): n-=1 yield n for i in xrange(5): print(i)
结果:spa
''' 4 3 2 1 0 '''
这种独特语法现象的缘由,从书中摘出相关资料以下:设计
当函数中使用yield产生一个值的时候,调用函数会返回一个generator对象,也就是一个生成器,此对象有__next__()方法,一般会调用next()调用该方法取出下一个产生的值,若没法产生下一个值,就会发生StopIteration这样的异常 --《Python程序设计教程》code
除了解释以上现象,反之也可推测 for in 函数的参数能够是生成器,生成器具备惰性求值特色,推测以前遇到过惰性求值的都是生成器(推测)orm
yield能够经过send函数来产生值,下面用一个课本上的DEMO来熟悉其相关函数的使用,课本完成了一个生产者消费者模型:对象
import random def producer(): while True: data=random.randint(0,9) print('生产了:',data) yield data def consumer(): while True: data=yield print('消费了:',data) def clerk(jobs,producer,consumer): print('执行了{}次生产与消费'.format(jobs)) p=producer() c=consumer() next(c) #这里容易出错 for i in range(jobs): data=next(p) c.send(data) clerk(5,producer,consumer)
上面注释的地方比较有意思,只是执行一次yield,而没有任何输出,彷佛是没用,可是删除以后程序却没法执行,个人理解是必须执行一次使值转化成生成器对象才能接受相关数据。blog
为了印证个人观点,执行如下代码:教程
print(type(producer)) print(type(producer()))
输出:
''' <class 'function'> <class 'generator'> '''