python的 装饰器 语法糖


什么是装饰器

装饰器是在不改变被装饰对象的 "内部代码" 和 "调用方式" 的基础上再增加额外的功能

装饰器的固定模板

1 def outer(func):
2     def inner(*args,**kwargs):
3         #函数执行之前要执行的代码4         res = func(*args,**kwargs)
5         #函数执行之后要执行的代码6         return res
7 
8     return inner

装饰器的语法糖 :@函数名

装饰器语法糖的执行流程:
        把语法糖下面紧贴着的函数名当成参数传递给装饰器函数参数

多层语法糖的执行顺序:

  紧贴函数名的 @函数名 依次往上

装饰器案例

 1 # 调用index函数,调用之前,需要输入用户名和密码,并且,用户名和密码必须输入正确
 2 # 并且登录成功之后,只需要认证一次,就可以用其他功能
 3 
 4 def home():
 5     print('from home')
 6 
 7 
 8 def login():
 9     print('from login')
10 
11 
12 is_auth = {'is_login': False}
13 
14 
15 def login_auth(func):
16     # func = index
17     def auth():
18         # 判断是否已经认证成功了
19         if is_auth.get('username'):
20             res = func()
21             return res
22         # 1. 让用户输入用户名和密码
23         username = input('username:').strip()
24         password = input('password:').strip()
25 
26         # 2. 判断用户名和密码
27         if username == 'ly' and password == '123':
28             func()
29             is_auth['is_login'] = True
30         else:
31             print('输入错误,不能调用函数')
32 
33     return auth  # 一定别忘记把内层函数的函数名返回出去
34 
35 
36 # auth(index)
37 # auth(home)
38 index = login_auth(index)  # res => auth
39 index()  # auth()
40 
41 home = login_auth(home)
42 home()
43 
44 login = login_auth(login)
45 login()

有参装饰器

 1 # 认证装饰器
 2 def outter(source_data, a, b,c):
 3     # source_data = 'file'
 4     def login_auth(func):
 5         # func = index
 6         def auth( *args, **kwargs):
 7             # 1. 让用户输入用户名和密码
 8             # username = input('username:').strip()
 9             # password = input('password:').strip()
10             if source_data == 'file':
11                 print('从文件中读数据')
12             elif source_data =='mysql':
13                 print('从mysql中读取数据')
14             elif source_data == 'oracle':
15                 print('从oracle中读取数据')
16 
17 
18         return auth  # 一定别忘记把内层函数的函数名返回出去
19     return login_auth
20 @outter('file', 1, 2,3)  # outter('file')    @login_auth
21 def index():
22     pass
23 index()

判定语法糖顺序案例

 1 # 判断七句print执行顺序
 2 def outter1(func1):
 3     print('加载了outter1')
 4     def wrapper1(*args, **kwargs):
 5         print('执行了wrapper1')
 6         res1 = func1(*args, **kwargs)
 7         return res1
 8     return wrapper1
 9 
10 def outter2(func2):
11     print('加载了outter2')
12     def wrapper2(*args, **kwargs):
13         print('执行了wrapper2')
14         res2 = func2(*args, **kwargs)
15         return res2
16     return wrapper2
17 
18 def outter3(func3):
19     print('加载了outter3')
20     def wrapper3(*args, **kwargs):
21         print('执行了wrapper3')
22         res3 = func3(*args, **kwargs)
23         return res3
24     return wrapper3
25 
26 
27 @outter1
28 @outter2
29 @outter3
30 def index():
31     print('from index')
32 index()

相关