带有yield关键字的函数都是生成器函数;
yield 关键字和return 一样都是必须要出现在函数内部; 并且yield 关键字不能和return 同时出现在一个函数内部;
def generator(): #由于该函数带有yield关键字 所以该函数是一个生成器函数 print('哈哈哈哈') yield '哈哈哈哈' g=generator() #g是一个生成器 print(g)
生成器函数被调用时,生成器函数内部的代码并不会执行,生成器也有__next__()方法和__iter__()方法,所以生成器也是一个迭代器;
可以使用g.__next__()方法来执行生成器函数内部的代码,但是该方法遇到yield就停止,并且会将yield的内容返回给生成器;下次再g.__next__()时会接着执行生成器函数内下面的代码,遇到下一个yield会再停止,然后返回一个值给生成器g;
def generator(): #由于该函数带有yield关键字 所以该函数是一个生成器函数 print('哈哈哈哈') yield '嘻嘻嘻嘻' g=generator() #g是一个生成器 #print(g) print(g.__next__())
如果生成器内部有多个yield 就可以使用多个g.__next__()方法进行获取返回值,继而打印:
def generator(): #生成器函数 print(1) yield "哈哈哈哈" print(2) yield "嘻嘻嘻嘻" print(3) yield "嘻嘻哈哈" g=generator() #g是一个生成器,有__next__()方法 可以打印yield返回的结果 ret=g.__next__() #会执行生成器函数内部的代码,并且遇到yield就停止,并且把yield的结果返回给ret print(ret) ret=g.__next__() #会接着执行后面的代码,遇到下一个yield停止,并且把yield的结果返回 print(ret) ret=g.__next__() print(ret)
其实会发现如果生成器函数内部有多个yield 后面得需要很多个g.__next__()配合才能接受yield的返回值,很麻烦,我们对于生成器可以使用for循环一次打印所有内容:
def generator(): for i in range(20): yield "今天星期五" #这个生成器有20个yield ,当next方法作用时才会执行一个yield g=generator() count=0 for i in g: #我的理解是i类似于i=g.__next__() 是生成器函数内部代码执行 遇到yield 停止将值返回给i count+=1 print(i,count)
而且就算我这次只打印了10个就退出了,下次再g.__next__()还是会从原来停止的地方接着开始执行!!
def generator(): for i in range(10): yield "哈哈哈哈" g=generator() count=0 for i in g: count+=1 print(i, count) if count==5: break for i in g: count+=1 print(i, count) #上面执行了5个yield 就强制break了,现在重新next一下还是从第六个开始打印的!
def generator(): for i in range(5): yield i g1=generator() g2=generator() #g1 和 g2是两个不同的生成器对象!! print(g1.__next__()) print(g1.__next__()) print(g1.__next__()) print(g1.__next__()) print(g2.__next__()) #仍然从0 开始
使用生成器监听文件输入
我们可以写一个普通函数通过打开一个文件,通过向文件里面输入内容 实时输出,完成文件监听效果:
with open('info',mode='r',encoding='utf-8') as file: while True: #不停的读取下一行内容 line=file.readline() #一行一行读 if line.strip(): print(line.strip())
但是如果我们想对读取到的内容做一个处理,比如每次输入的内容是否含有‘python’字样等,有的话在其前面打印****在输出:
我们不能使用return 来接收,因为这样只能读取到第一行的内容就停止了,我们需要不听的往下读,在接收,需要用到yield 关键字:
def generator(): with open('info',encoding='utf-8') as file: while True: line=file.readline() if line.strip(): yield line.strip() g=generator() for i in g: # i是每一行获取到的内容 被yield返回的 i相当于g.__next__()方法 if 'python' in i: print('****',i)
上面 就是用生成器完成了文件监听功能,并且可以完成输入内容的过滤,文件的监听过滤~