首页 > 代码库 > 装饰器,迭代器,生成器
装饰器,迭代器,生成器
一、装饰器
无参装饰器:
1、示例1:
1 import time #加载时间模块 2 def war(name): #定义装饰器 3 def wari(): 4 start = time.time() #定义开始时间 5 name() #相当于执行下面的函数 6 stop = time.time() #定义结束时间 7 print("run time is %s" %(stop-start)) #给原来函数加入的新功能 8 return wari 9 @war 10 def info(): 11 time.sleep(3) 12 print(‘we are famly!!‘) 13 14 info()
执行@war的时候就表示运行了war(name)这个函数,然后把下面的函数名赋值给name,就表示info=war(info),现在取到的只是info这个函数的内存地址,在装饰器上运行name()就相当于执行这个info()函数
示例2:
1 def war(name):
2 def wari(*args,**kwargs):
3 start = time.time()
4 name(*args,**kwargs)
5 stop = time.time()
6 print("run time is %s" %(stop-start))
7 return wari
8 @war
9 def info():
10 time.sleep(3)
11 print(‘we are famly!!‘)
12
13 @war
14 def auth(name,password):
15 time.sleep(2)
16 print(‘login success!‘)
17
18 @war
19 def ero(x):
20 time.sleep(1)
21 print(‘hello %s‘ %x)
22
23 info()
24
25 auth(‘xyy‘,123)
26 ero(‘xyp‘)
有参装饰器:
示例1:
1 def auth1(auth_type):
2 def auth(func):
3 def war(*args,**kwargs):
4 if auth_type == ‘file‘:
5 name = input("username: ")
6 pwd = int(input("password: "))
7 if name == "xyy" and pwd == 123:
8 print("login successfull!")
9 func(*args,**kwargs)
10 else:
11 print("login error!")
12 elif auth_type == ‘sql‘:
13 print(‘输入错误‘)
14 return war
15 return auth
16
17
18 @auth1(auth_type=‘sql‘) #write=auth(write)
19 def write():
20 print(‘welcome to my home!‘)
21 write()
二、迭代器
1、例子1:有下标的类型
1 l = [‘a‘,‘b‘,‘c‘,‘d‘,‘e‘] #定义一个列表
2 i = l.__iter__() #生成一个迭代器
3
4 while True: #循环这个生成器
5 try: #监听
6 print(i.__next__()) #循环取下一个值
7 except StopIteration: #监听的关键字
8 break #退出循环
9
10 或:
11 i = 0
12 while i < len(l):
13 print(l[i])
14 i += 1
15
16 或:
17 for i in l: #直接循环遍历一遍
18 print(i)
19
20 或:
21 for i in range(len(l)): #先取下标的的长度再取对应的值
22 print(l[i])
23 PS:try和except相当于一个if判断
例子2:没下标的类型
1 dic = {‘a‘:1,‘b‘:2,‘c‘:3}
2 i = dic.__iter__()
3 while True:
4 try:
5 print(i.__next__())
6 except StopIteration:
7 break
例子3:文件类型
1 with open(‘war.txt‘,‘r+‘,encoding=‘utf8‘) as f:
2 a = f.__iter__()
3 while True:
4 try:
5 print(a.__next__(),end=‘‘)
6 except StopIteration:
7 break
2、判断是否是可迭代和是否是迭代器:
1 from collections import Iterable,Iterator #加载模块
2 s = "xyyp"
3 l = [‘a‘,‘b‘,‘c‘]
4 t = (1,2,3,4)
5 d = {"s":1,"a":4}
6 f = open(‘war.txt‘)
7 (1)Iterable判断是否可迭代:
8 print(isinstance(s,Iterable)) -->True
9 print(isinstance(l,Iterable)) -->True
10 print(isinstance(t,Iterable)) -->True
11 print(isinstance(d,Iterable)) -->True
12 print(isinstance(f,Iterable)) -->True
13 (2)Iterator判断是否是迭代器:
14 print(isinstance(s,Iterator)) -->False
15 print(isinstance(l,Iterator)) -->False print(isinstance(t,Iterator)) -->False
16 print(isinstance(d,Iterator)) -->False
17 print(isinstance(f,Iterator)) -->True
PS:只有文件是可迭代对象并且是迭代器。
小结:
迭代器优点:
1,迭代器提供了一种不依赖于索引的取值方式,这样可以遍历那些没有索引的可迭代对象,比如:字典,集合,文件。
2,迭代器于列表比较,迭代器是惰性计算的,更节省内存空间。
迭代器缺点:
1,无法获取迭代器的长度,使用不如列表索引取值灵活。
2,一次性,只能往后取值,不能倒着取值
三、生成器和协程函数
1、生成器就是一个函数,这个函数内包含有yield这个关键字。
2、生成器和和return的区别在于return只能返回一次函数的值就结束了,yield能返回多次值。
3、yield把函数变成了生成器,生成器也就是迭代器。
示例1:
1 def count(x): #定义函数
2 print(‘start count‘)
3 while x > 0: #函数内容
4 yield x #返回值
5 x -= 1
6 print(‘done‘)
7
8 g = count(5) #执行函数 并把返回值赋给一个变量,最后生成迭代器
9 while True: #while循环迭代器
10 try:
11 print(next(g))
12 except StopIteration:
13 break
4、协程函数:
示例1:
1 def eater(name): #定义函数
2 print(‘%s waiting food‘ %name)
3 food_list=[] #定义空列表
4 while True:
5 food = yield food_list #yield返回值赋值给food
6 print(‘%s get %s,to start eat‘ %(name,food))
7 food_list.append(food) #每传入一个值添加到列表里面去
8
9 e = eater(‘钢蛋‘) #生成迭代器
10 print(next(e)) #输出迭代器内容
11 print(e.send(‘包子‘)) #send传入的值可以直接赋给yield
12 print(e.send(‘大葱包子‘))
13 print(e.send(‘大蒜包子‘))
14 print(e.send(‘韭菜包子‘))
小结:
send和next()的区别:
1、如果函数内yield是表达式形式(food=yield),那么必须先next触发函数的执行。
2、二者的共同之处都可以让函数在上一次暂停的位置继续运行,不同之处在于send在触发下一次代码的执行时,会顺便给yield传一个值。
四、面向过程函数编程:
示例:
1 import os #加载os模块
2 def decorate(func): #定义next装饰器
3 def t_layer(*args,**kwargs):
4 res = func(*args,**kwargs)
5 next(res)
6 return res
7 return t_layer
8
9 @decorate #调用装饰器
10 def path(target): #定义文件路径生成器
11 while True:
12 dir_name = yield
13 g = os.walk(dir_name)
14 for i in g:
15 for x in i[-1]:
16 file_path = "%s\\%s" %(i[0],x)
17 target.send(file_path)
18
19 @decorate
20 def opener(target): #定义读取文件内容的生成器
21 while True:
22 file_path = yield
23 with open(file_path) as f:
24 target.send((file_path,f))
25
26 @decorate
27 def cat(target): #定义看文件内容的生成器
28 while True:
29 file_path,f = yield
30 for line in f:
31 target.send((file_path,line))
32
33 @decorate
34 def grep(pattern,target): #定义一个过滤文件内容的生成器
35 while True:
36 file_path,line = yield
37 if pattern in line:
38 target.send(file_path)
39
40 @decorate
41 def printer(): #定义输出指定文件路径的生成器
42 while True:
43 file_path =yield
44 print(file_path)
45
46 g = path(opener(cat(grep(‘xlinux‘,printer())))) #调用生成器
47 g.send(‘D:\\xyyp‘)
优点:
1、体系结构更加清晰。
2、简化程序的复杂度。
缺点:
1、可扩展极其的差,所以面向过程的应用场景是:不需要经常变化的软件。
装饰器,迭代器,生成器