20函数----生成器(generator)
生成器(generator)是迭代器()的一种,其本质上就是迭代器
分为生成器函数、生成器表达式
1、生成器函数
只要函数内部含有yield关键字,那么函数名()的结果就是生成器,并且不会执行函数内部代码
例1:
def func(): print('--------first') yield 1 #相当于return,是第一次__next__()的返回值,会保存函数的运行状态挂起函数 print('---------second') yield 2 print('---------third') yield 3 print('end') g = func() #不会执行代码 print(g) #<generator object func at 0x0000009F9D3D94C0> # # 生成器内含__iter__()、__next__()方法,所以生成器就是迭代器。接上面函数,得到函数结果 print(g.__next__()) print(g.__next__()) # 或者用for循环迭代 for i in g: print(i)
2、模拟实现range()
def my_range(start, stop, setp=1): while start < stop: yield start start += setp g = my_range(1,8,2) print(next(g)) print(next(g)) print(next(g)) print(next(g))
3、模拟实现 tail -f | grep '404'
# tail 命令可用于查看文件的内容,参数 -f 常用于查阅正在改变的日志文件。 # grep 命令用于查找文件里符合条件的字符串 import time def tail(filepath): with open(filepath,'rb') as f: f.seek(0, 2) # 使用seek()方法,则文件打开方式必须是'rb'(这句话错了。。。),0为偏移量, 2表示从文件末尾算起 while True: line = f.readline() if line: yield line else: time.sleep(2) def grep(pattern, lines): for line in lines: line = line.decode('utf-8') if pattern in line: yield line for line in grep('404', tail('data.txt')): print(line)
4、send()
def eater(): print('ready to eat') while True: #感觉这里一般都要有一个死循环,用来持续接收g.send() food = yield #1 yield相当于函数的return 2、food = yield,接受send()传过来的值,赋值给food,并让生成器继续向下运行 print('eat the food:【{}】...'.format(food)) g = eater() next(g) #需要事先“初始化”一次,让函数挂起在food=yield,等待调用g.send()方法为其传值 g.send('包子') g.send('apple') g.send('orange')
可以用装饰器来完成为所有表达式形式yield对应生成器的初始化操作
def init(func): def wrapper(*args, **kwargs): g = func(*args, **kwargs) next(g) #完成首次的“初始化” return g return wrapper @init #eater=init(eater) def eater(): print('ready to eat') while True: food = yield print('eat the food:【{}】...'.format(food)) g = eater() g.send('ccccc') g.send('hhhhh')
def init(func): def wrapper(*args, **kwargs): g = func(*args, **kwargs) next(g) #完成首次的“初始化” return g return wrapper @init def eater(): print('ready to eat...') food_list = [] while True: food = yield food_list #后面g.send('aaa')的值发送给yield=food,后面的food_list是函数的返回值 food_list.append(food) print(food_list) g = eater() # 这时候的 g 已经是装饰器里“初始化”后返回的 g 了 g.send('aaa') g.send('bbbb') g.close()#结束迭代
5、最简单的生产者消费者
import time def init(func): def wrapper(*args, **kwargs): g = func(*args, **kwargs) next(g) #完成首次的“初始化” return g return wrapper @init def consumer(name): print('i am {}, ready to eat....'.format(name)) while True: food = yield print(food) print('{} eating...'.format(name)) def producer(): c1 = consumer('cc')#这里就是运行了consumer(),函数挂起在food=yield,等待调用g.send()方法为其传值 c2 = consumer('dd') for i in range(10): c1.send('生产了包子{}'.format(i)) c2.send('生产了包子{}'.format(i)) time.sleep(2) producer()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-04-03 02python基础----控制流程