迭代器,python里提供类似装饰器一样的一种语法。
# 依赖下标循环的方法
l = ['a','b','c','d','e']
i = 0
while i < len():
print(l[i])
i+=1
# for循环形式迭代
for i in range(len(l)):
print(l[i])
迭代器
只要对象本身有__iter__方法,那它就是可迭代的,只要执行这个方法,它的返回值就是迭代器,这个返回值就有个__next__方法.
dic = {'a':1,'b':2,'c':3}
i = __iter__(dic)
print(i.__next__())
print(i.__next__())
print(i.__next__())
print(i.__next__())
# 当取的值多于元素本身会抛出StopIteration错误,也可以理解为终止信号
# 为避免爆出异常可以这么做
i = iter(d)
while True:
try:
print(print(next(i))
excet StopIteration:
break
# python里面的for循环的方式不是按照下标而是将你传入的对象变成迭代器,去__next__
# 在文件中,文件句柄即时迭代器,也是可迭代对象
# 为什么要用迭代器
1.如果像字典,集合,这种无序的又或者文件这种没有索引的,你没有办法像下标那样的取值
2.迭代器的取值方式是统一的,大家都是按照next的方式取值,迭代器的方式取值占内存比列表这种索引取值更节省内存,他next()一下才会生成一个值属于惰性计算。
# 缺点
1.迭代器无法统计有多长,只有到最后一步才能知道多长。指定取值的话,必须一步步的取值下去才能取到。所以使用不灵活
2.迭代器是一次性取值,不能回头。
了解就好了哈
查看可迭代对象
from collections import Iterable,Iterator
s = "hello"
l = [1,2,3]
t = (1,2,3)
d = {'a':1}
set1 = {1,2,3,4}
f = open('a.txt')
s.__iter__()
l.__iter__()
t.__iter__()
d.__iter__()
set1.__iter__()
f.__iter__()
f.__iter__()
print(isinstance(s,Iterable))
生成器
- 生成器就是一个函数,这个函数内包含有yield这个关键字,生成器是用来生成值的。 生成器也是一种迭代器所以可以 next(g),生成器把函数做成一个迭代器。
- 生成器与return的区别,return只能执行一次而yield可以执行多次,返回多次值
- yield 是把函数变成了迭代器,它使函数可迭代,函数也能够拥有yield使用
from collections import Iterator
def test():
print('first')
yield 1
yield 2
yield 3
g= test()
print(g) #g是一个函数
print(isinstance(g,Iterator)) #判断类型
print(next(g))
print(next(g))
for i in g:
print(i)
# 生成流程案例
def test(n):
print('start')
while n>0:
yield n
n -= 1
print('done')
g = test(6)
for i in g:
print(i)
# 生成器场景案例,模仿tail -f /tmp/a.txt | grep 'error'
案例1:作用监控文件改变,类似linux下的tail命令。
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)
print('>>>') #这里打印表示他在一直监控这个文件,程序不是卡死
continue
else:
#print(line,end="")
yield line
g = tail('a.txt')
#print(g.next())
for line in g:
print(line)
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)
# print('====>')
continue
else:
#print(line,end='')
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)
#next触发执行g2生成器函数
for i in g2:
print(i)
- 协程
- 协程是用到.send方法,它会去给yield传个值,达到管道的作用,他的作用和next方法相似,但是多了一个传值的步骤
def eater(name)
print('%s start to eat food' %(name)
while True:
food = yield
print('%s get %s ,to start eat'%(name,food)
print('done')
name_yield = eater('alex')
next(e)
name_yield.send('包子')
name_yield.send('烧麦')
name_yield.send('饺子')
def eater(name)
print('%s start to eat food' %(name)
food_list = []
while True:
food = yield food_list
print('%s get %s ,to start eat'%(name,food)
food_list.append(food)
print('done')
name_yield = eater('alex')
next(e)
name_yield.send('包子')
name_yield.send('烧麦')
name_yield.send('饺子')