首页 > 代码库 > python基础----迭代器、生成器、协程函数
python基础----迭代器、生成器、协程函数
一、什么是迭代器协议
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)
2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。
二,为什么要用迭代器
优点:
1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)
2:迭代器与列表比较,迭代器是惰性计算的,更节省内存
缺点:
1:无法获取迭代器的长度,使用不如列表索引取值灵活
2:一次性的,只能往后取值,不能倒着取值
1 l=[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘]2 i=l.__iter__()3 while True:4 try:5 print(next(i))6 except StopIteration:7 break
1 d={‘a‘:1,‘b‘:2,‘c‘:3}2 d.__iter__3 for k in d: #d.__iter__()4 print(k)
1 s={1,2,3,4} 2 for i in s: 3 print(i) 4 5 with open(‘a.txt‘,‘r‘) as f: 6 for line in f: 7 print(line) 8 9 f=open(‘a.txt‘,‘r‘)10 f.__next__11 f.__iter__12 print(f)13 print(f.__iter__())14 15 for line in f: #f.__iter__()16 print(line)17 18 i=f.__iter__()19 20 while True:21 try: #异常排查,与StopIteration一起用22 print(next(i))23 except StopIteration: #异常排查,与try一起用 # except 排除24 break
1 l=[1,2,3] 2 print(len(l)) 3 i=l.__iter__() 4 5 print(next(i)) 6 print(next(i)) 7 print(next(i)) 8 print(next(i)) 9 10 11 for x in i:12 print(x)13 for x in i:14 print(x)15 for x in i:16 print(x)17 for x in i:18 print(x)
1 查看可迭代对象与迭代器对象 2 3 from collections import Iterable,Iterator 4 5 s=‘hello‘ 6 l=[1,2,3] 7 t=(1,2,3) 8 d={‘a‘:1} 9 set1={1,2,3,4}10 f=open(‘a.txt‘)11 12 都是可迭代的13 s.__iter__()14 l.__iter__()15 t.__iter__()16 d.__iter__()17 set1.__iter__()18 f.__iter__()19 print(isinstance(s,Iterable))20 print(isinstance(l,Iterable))21 print(isinstance(t,Iterable))22 print(isinstance(d,Iterable))23 print(isinstance(set1,Iterable))24 print(isinstance(f,Iterable))25 26 查看是否是迭代器27 print(isinstance(s,Iterator))28 print(isinstance(l,Iterator))29 print(isinstance(t,Iterator))30 print(isinstance(d,Iterator))31 print(isinstance(set1,Iterator))32 print(isinstance(f,Iterator))
三、生成器
什么是生成器:
可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象.
from collections import Iterator 生成器就是一个函数,这个函数内包含有yield这个关键字.
生成器分类及在python中的表现形式:(Python有两种不同的方式提供生成器)
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行.
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表.
为何使用生成器:
优点:
Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。
生成器小结:
1.是可迭代对象
2.实现了延迟计算,省内存
3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处,记住喽!!!
生成器与return的区别:return只能返回一次函数就彻底结束了,而yield能返回多次值
yield功能:
1.yield把函数变成生成器-->生成器本质就是迭代器
2.用return返回值能返回一次,而yield返回多次
3.函数暂停以及继续运行的状态是通过yield保存的
1 def test(): 2 print(‘one‘) 3 yield 1 #return 1 4 print(‘two‘) 5 yield 2 #return 2 6 print(‘three‘) 7 yield 3 #return 2 8 print(‘four‘) 9 yield 4 #return 210 print(‘five‘)11 yield 5 #return 212 13 g=test()14 print(g)15 # print(isinstance(g,Iterator))16 g.__iter__()17 g.__next__()18 19 res=next(g)20 print(res)21 22 res=next(g)23 print(res)24 25 res=next(g)26 print(res)27 28 res=next(g)29 print(res)30 31 for i in g:32 print(i)
1 def func():2 n=03 while True:4 yield n5 n+=16 7 f=func()8 print(next(f))
1 import time 2 def tail(file_path): 3 with open(file_path,‘r‘) as f: 4 f.seek(0,2) 5 while True: 6 line=f.readline() 7 if not line: 8 time.sleep(0.3) 9 continue10 else:11 # print(line)12 yield line13 tail(‘/tmp/a.txt‘)
四、协程函数
定义:如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数成为协程函数
#例子
1 def eater(name): 2 print(‘%s start to eat food‘ %name) 3 food_list=[] 4 while True: 5 food=yield food_list 6 print(‘%s get %s ,to start eat‘ %(name,food)) 7 food_list.append(food) 9 print(‘done‘)10 e=eater(‘钢蛋‘)11 print(e)12 print(next(e))13 print(e.send(‘包子‘))14 print(e.send(‘韭菜馅包子‘))15 print(e.send(‘大蒜包子‘))
为协程函数添加装饰器:
1 def timmer(func): 2 def wrapper(*args,**kwargs): 3 e=func(*args,**kwargs) 4 next(e) 5 return e 6 return wrapper 7 8 @timmer #eater=timmer(eater) 9 def eater(name):10 print(‘%s start to eat food‘ %name)11 food_list=[]12 while True:13 food=yield food_list14 print(‘%s get %s ,to start eat‘ %(name,food))15 food_list.append(food)16 e = eater(‘egon‘) #wrapper(‘egon‘)17 # print(e)18 # next(e)19 print(e.send(‘包子‘))20 print(e.send(‘包子‘)) #以下每send一次都会执行一次结果21 print(e.send(‘包子‘))22 print(e.send(‘包子‘))
补充:
1 def init(func): 2 def wrapper(*args,**kwargs): 3 res=func(*args,**kwargs) 4 next(res) 5 return res 6 return wrapper 7 8 @init #eater=init(eater) 9 def eater(name):10 print(‘%s start to eat‘ % name)11 food_list=[]12 while True:13 food = yield food_list14 print(‘%s eat %s‘ % (name, food))15 food_list.append(food)16 17 e = eater(‘zhejiangF4‘) #wrapper(‘zhengjiangF4‘)18 # print(e)19 # next(e) #e.send(None)20 21 print(e.send(‘123‘))22 print(e.send(‘123‘))23 print(e.send(‘123‘))24 print(e.send(‘123‘))25 print(e.send(‘123‘))
五、协程函数的应用
面向过程的编程思想:流水线式的编程思想,在设计程序时,需要把整个流程设计出来
优点: 1:体系结构更加清晰
2:简化程序的复杂度
缺点:可扩展性极其的差,所以说面向过程的应用场景是:不需要经常变化的软件,如:linux内核,httpd,git等软件
旁白: 此实例包含了装饰器、迭代器、生成器、协程函数、os模块中walk命令,需要好好记住! ?????
1 #grep -rl ‘python‘ C:\egon 2 import os,time 3 def init(func): 4 def wrapper(*args,**kwargs): 5 res=func(*args,**kwargs) 6 next(res) 7 return res 8 return wrapper 9 10 #找到一个绝对路径,往下一个阶段发一个11 @init12 def search(target):13 ‘找到文件的绝对路径‘14 while True:15 dir_name=yield #dir_name=‘C:\\egon‘16 print(‘车间search开始生产产品:文件的绝对路径‘)17 time.sleep(2)18 g = os.walk(dir_name)19 for i in g:20 # print(i)21 for j in i[-1]:22 file_path = ‘%s\\%s‘ % (i[0], j)23 target.send(file_path)24 25 @init26 def opener(target):27 ‘打开文件,获取文件句柄‘28 while True:29 file_path=yield30 print(‘车间opener开始生产产品:文件句柄‘)31 time.sleep(2)32 with open(file_path) as f:33 target.send((file_path,f))34 35 @init36 def cat(target):37 ‘读取文件内容‘38 while True:39 file_path,f=yield40 print(‘车间cat开始生产产品:文件的一行内容‘)41 time.sleep(2)42 for line in f:43 target.send((file_path,line))44 45 @init46 def grep(pattern,target):47 ‘过滤一行内容中有无python‘48 while True:49 file_path,line=yield50 print(‘车间grep开始生产产品:包含python这一行内容的文件路径‘)51 time.sleep(0.2)52 if pattern in line:53 target.send(file_path)54 55 @init56 def printer():57 ‘打印文件路径‘58 while True:59 file_path=yield60 print(‘车间printer开始生产产品:得到最终的产品‘)61 time.sleep(2)62 print(file_path)63 64 65 g=search(opener(cat(grep(‘python‘,printer()))))66 g.send(‘C:\\egon‘)67 g.send(‘D:\\dir1‘)68 g.send(‘E:\\dir2‘)
python基础----迭代器、生成器、协程函数