python学习篇之【生成器、迭代器】
一、生成器简介
生成器:可以当做是一种数据类型,遵循迭代器协议,是一种可迭代对象。
特点:这种数据类型自动实现了迭代器协议,提供next()方法
创建生成器对象的两种方式:
1、函数方式
使用 yield 作为函数的返回值。
2、生成器表达式
item=(i for i in range(10))
# 类似三元表达式
例:item_list = [i for i in range(10)]
注:这是比较好的编程习惯,但并不能应用在大量数据之中
3、总结
语法上:与函数类似,差别在生成器使用yeild语句作为返回值。
自动实现迭代器协议,不用像列表等数据类型执行iter方法,可以直接next。
状态挂起:生成器使用yeild语句返回一个值,yeild挂起该函数的运行状态,以便从上一次终止的状态继续运行。
优点:
1、延迟计算,优化数据处理,一次返回一个结果,而不是一次生成所有结果,占用大量内存。
2、提高代码可读性,(保证可读性的前提,减少代码量)
注意:生成器只能遍历一次,不止for循环能遍历生成器,其他函数如,list sum 都可以遍历。
# 生成器函数 例: # import time # def y_test(): # print("母鸡下蛋准备") # time.sleep(3) # yield "第一颗鸡蛋" # time.sleep(3) # yield "第二颗鸡蛋" # time.sleep(3) # yield "第三颗鸡蛋" # res = y_test() # print(res.__next__()) # print(res.__next__()) # print(res.__next__())
二、生产者消费者模型
函数之间相互调用,等待切换,无形中窥探到了单线程,多并发。
import time def produser(name): print('%s 我开动了'%name) for i in range(1,3): time.sleep(2) yield print("%s 吃了 %s 个包子" % (name, i) time.sleep(2) print('吃完了') def consumer(): name="小智" e = produser(name) try: while True: next(e) except StopIteration: print("吃饱了") consumer()
三、生成器练习之【模拟管道功能】tail -f access.log |'404:
# message.txt 文件内容 2022/1/15 09:18 192.168.1.103 watch AV.mv.mp4 2022/1/15 22:04 192.168.1.111 watch AV.mv 2022/1/16 07:20 192.168.0.12 watch AV.mv # 代码 def my_tail(file): # tail 拿到文件最后一行的二进制内容 with open(file,'rb',) as data: data.seek(0,2) # 移动到文件的最后一行 while True: line = data.readline() # line 等于 最后一行的行内容 if line: # 判断是否为空行 yield line # 如果不是空行,返还 行内容给 line —> my_tail 等待继续调用 else: time.sleep(2) # 如果为空行的,休息2秒再进行判断 def my_grep(err_msg,tail): # 传入 错误信息 、 tail 函数(拿到文件最后一行内容) for i in tail: # 循环 tail传入的 最后一行内容 line = i.decode() # 解码 该行内容 赋值给 line if err_msg in line: # 如果传入的 err_msg 在 line 里 yield line # yield 的返回值为 line 传入—> my_grep 然后等待下一次调用。 for i in my_grep("带病毒的软件",my_tail('message_log.txt')): #过滤带病毒的软件 print(i)

浙公网安备 33010602011771号