使用装饰器:不改变函数本身并新增功能
装饰器:本质也是一个函数(嵌套函数+高阶函数)
1、返回值:函数对象(内层函数)
2、在被装饰函数之前@装饰器函数
3、被装饰函数需要传参:装饰器内部函数也需要传参,写成inner(*args,**kwargs)适用多个被装饰函数
4、装饰器需要传参:则在装饰器外需再套一层函数




1 # 被装饰函数有参数时,在装饰器内层函数也要有对应参数
2 import time
3 def timer(func):
4 def inner(*args,**kwargs):
5 start_time = time.time()
6 func(*args,**kwargs)
7 stop_time = time.time()
8 print('the func run time is %s'%(stop_time-start_time))
9 return inner
10
11 @timer # test1=timer(test1) return inner 即test1=inner
12 def test1(arg):
13 time.sleep(1)
14 print('in the test1,arg is %s'%arg)
15 @timer
16 def test2():
17 time.sleep(1)
18 print('in the test2')
19 test1('123') # 执行到这里时 test1('123')=inner('123')
20 test2()


装饰器本身需要传参时,需要再嵌套一层函数


1 # 装饰器本身需要传参
2 user,passwd = 'admin','123456'
3 def auth(auth_type):
4 print('auth func ',auth_type)
5 def outer_wrapper(func):
6 def wrapper(*args,**kwargs):
7 print('wrapper func args',*args,**kwargs)
8 if auth_type == 'local':
9 username = input('Username:').strip()
10 password = input('Password:').strip()
11 if username == user and password == passwd:
12 # 设置颜色开始 :\033[显示方式;前景色;背景色m
13 print('\033[0;32;47;1mUser has passed authentication\033[0m')
14 res = func(*args,**kwargs)
15 print('---after authentication')
16 return res # 被装饰函数有返回值
17 else:
18 print('\033[0;31;47;1mInvalid username or password\033[0m')
19 elif auth_type == 'ldap':
20 print('不需要验证')
21 return wrapper
22 return outer_wrapper
23
24 def index():
25 print('welcome to index page')
26 @auth(auth_type='local') #home = wrapper :auth() -->return outer_wrapper -->outer_wrapper()-->return wrapper
27 def home():
28 print('welcome to home page')
29 return 'from home'
30 @auth(auth_type='ldap')
31 def bbs():
32 print('welcome to bbs page')
33
34 index()
35 print(home())
36 bbs()