1 生成器
1.1 生成器定义
生成器就是一个函数,有yield关键字,主要是针对函数的
1 2 3 4 5 6 7 8 9
| from collections import Iterable,Iterator def test(): print("test") yield 1 yield 2 g = test() print(g) print(isinstance(g,Iterator))
|
结果:
generator object test at 0x00000000027FC780
True
返回结果是证明生成器就是迭代器
证明了是迭代器,迭代器可以用next()执行,这里就是next(g)
结果是:
test
1
结果是执行了一个test,并返回了一个1
再写一条print(next(g)),
结果是:
test
1
2
小结:
生成器是一个有yield 的函数,想要使用就要用next()f方法,运行一次next后会程序会停在yield,再次执行的时,会从yield这个位置继续向下执行。
1.2 生成器中的yield和函数return的区别
函数的返回值return的区别
return只能执行一次,函数就彻底结束
yield可以返回多次值
yield 可以保存运行状态
函数在暂停以及继续运行的状态是yield保存的
yield相当于把iter 和next 方法
1.3 生成器—>迭代器 for循环
1 2 3 4 5 6 7 8 9 10
| from collections import Iterable,Iterator def test(): print("test") yield 1,2,3 yield 2 g = test() for i in g: print(i)
|
结果:
test
(1, 2, 3)
2
yield 返回值是多个的时候,返回的是元组
牛逼之处:
自己能够定义一个函数,然后控制函数的返回值,把函数构造成一个序列类型,能够被for遍历
遇到迭代器,就用next()
1.4 迭代器计数
1 2 3 4 5 6 7 8 9 10 11 12 13
| def countdown(n): print("start") while n > 0: yield n n -=1 print('done') g = countdown(5) print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g))
|
这种情况下,但n=0的时候,有next就会找yield,但是最后不能进入while循环了,所以会报错
for循环的形式:
1 2 3 4 5 6 7 8 9 10
| def countdown(n): print("start") while n > 0: yield n n -=1 print('done') g = countdown(5) for i in g: print(i)
|
2 Python制作动态查看文件的内容—tail工具
tail -f 查看文件的时候,是一直在等待,直到有内容增加进来
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import time def tail(file_path): with open(file_path,'r') as f: f.seek(0,2) while True: line = f.readline() if not line: time.sleep(0.3) continue else: print(line,end='') tail('/tmp/a.txt')
|
这里遇到的问题是在open文件的时候,file_path加上了引号,就是思维定式了,不知道这里传入的是一个参数。
使用生成器的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import time def tail(file_path): with open(file_path,'r') as f: f.seek(0,2) while True: line = f.readline() if not line: time.sleep(0.3) continue else: yield line g = tail('/tmp/a.txt') for i in g: print(i,end='')
|
过滤动态添加的内容
使用的是管道的概念
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import time def tail(file_path): with open(file_path,'r') as f: f.seek(0,2) while True: line = f.readline() if not line: time.sleep(0.3) continue else: yield line g = tail('/tmp/a.txt') for i in g: if ‘error’ in i: print(i,end='')
|
通过添加判断能够过滤到error,但是这样就是写死了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import time def tail(file_path): with open(file_path,"r",encoding="utf-8") as f: f.seek(0,2) while True: line = f.readline() if not line: time.sleep(0.5) continue else: yield line def grep(pattern,lines): for line in lines: if pattern in line: print(line,end='') g = tail('/tmp/a.txt') grep('error',g)
|
把grep写成生成器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import time def tail(file_path): with open(file_path,"r",encoding="utf-8") as f: f.seek(0,2) while True: line = f.readline() if not line: time.sleep(0.5) continue else: yield line def grep(pattern,lines): for line in lines: if pattern in line: yield line g1 = tail('/tmp/a.txt') g2 =grep('error',g1) for i in g2: print(i)
|