1 装饰器的重要内容
2 functools.wraps
3 带参数的装饰器
4 多个装饰器装饰同一个函数
5
6
7
8 一.编写一个装饰器,为多个函数添加登陆认证的功能。具体:只需要登录一次,后面被装饰的函数不需要重新登陆。
9 FLAG = False
10 def wrapper(f):
11 def inner(*args,**kwargs):
12 global FLAG
13 if FLAG == True:
14 ret = f(*args, **kwargs)
15 return ret
16 else:
17 username = input('username:')
18 password = input('password:')
19 if username == 'daxiong' and password == '136320':
20 FLAG = True
21 ret = f(*args,**kwargs)
22 return ret
23 else:
24 print('登陆失败')
25 return inner
26 @wrapper
27 def a():
28 return '今晚中大奖'
29
30 @wrapper
31 def b():
32 return '奖金八百万'
33
34 print(a())
35 print(b())
36
37
38 二.带参数的装饰器:
39 def wrapper(f):
40 def inner(*args,**kwargs):
41 ret = f(*args,**kwargs)
42 return ret
43 return inner
44 @wrapper
45 def func():
46 return '双色球中奖800万' #.__name__是求出字符串格式的函数名,用于文件操作。
47 print(func.__name__) #因为func=inner,执行func相当于执行inner,所以执行结果是inner
48
49 from functools import wraps #加上这句话以及 @wraps(f),print(func.__name__)的执行结果是func.否则就是inner。
50 def wrapper(f):
51 @wraps(f) #带参数的装饰器,带参数的语法糖。
52 def inner(*args,**kwargs):
53 ret = f(*args,**kwargs)
54 return ret
55 return inner
56 @wrapper
57 def func():
58 return '双色球中奖800万'
59 print(func.__name__) #执行结果是func
60
61
62 三.带参数的装饰器,装饰多个函数,方便好用。FLAG相当于开关,当开关是True,被装饰的函数走的是计算时间的通道,当开关是False时,走另外一条通道。
63 FLAG = True #使用全局变量,True时,所有函数都被装饰,否则不被装饰。
64 import time
65 def wrapper(fl): #让语法糖带参数(传入全局变量),必须定义一个外层函数。最多三层。三层嵌套函数。
66 def timmer(f):
67 def inner(*args,**kwargs):
68 global FLAG
69 if FLAG:
70 start = time.time()
71 time.sleep(0.01)
72 ret = f(*args,**kwargs)
73 end = time.time()
74 print(end - start)
75 return ret
76 else:
77 print('当FLAG为False时,时间装饰器不起作用')
78 return inner
79 return timmer #timmer=wrapper(FLAG)
80 @wrapper(FLAG) #timmer=wrapper(FLAG),所以@wrapper(FLAG)就是@timmer
81 def a():
82 return '我要中双色球一等奖'
83 @wrapper(FLAG)
84 def b():
85 return '奖金800万'
86 print(a())
87 print(b())
#注意:带参数的装饰器是三层函数,由参数 FLAG=1,2,其他 来控制选择哪一种功能。
FLAG = 1 #FLAG=1,2,其他
import time
def wapper(f1):
def timmer(f):
def inner(*args,**kwargs):
global FLAG
if FLAG == 1:
start = time.time()
time.sleep(0.1)
n = f(*args, **kwargs)
end = time.time()
print(end-start)
return n
elif FLAG == 2:
print('2222')
n = f(*args, **kwargs)
return n
else:
print('其他')
n = f(*args, **kwargs)
return n
return inner
return timmer
@wapper(FLAG)
def f1():
print('f1111')
@wapper(FLAG)
def f2():
print('f22222')
f1()
f2()
91 四.使用多个装饰器来装饰同一个函数。用处:记录用户的登录情况,计算这个函数的执行时间。
92 def wrapper1(f):
93 def inner():
94 print('wrapper1 before')
95 f()
96 print('wrapper1 after')
97 return inner
98 def wrapper2(f):
99 def inner():
100 print('wrapper2 before')
101 f()
102 print('wrapper2 after')
103 return inner
104
105 @wrapper2
106 @wrapper1
107 def func():
108 print('明天继续加油')
109 func()
#wrapper2 before
#wrapper1 before
#明天继续加油
#wrapper1 after
#wrapper2 after