1、使用了 yield 的函数被称为生成器。
调用一个生成器函数,返回的是一个迭代器对象,并且不会执行函数内部代码。
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‘) c2 = consumer(‘dd‘) for i in range(10): c1.send(‘生产了包子{}‘.format(i)) c2.send(‘生产了包子{}‘.format(i)) time.sleep(2) producer()
原文:https://www.cnblogs.com/cc-world/p/14015502.html