装饰器


饰器简易版本

 1 # 给函数添加统计执行时间的功能
 2 
 3 def outer(func):  # func指向的是函数名index
 4     # func = index
 5     def get_time():
 6         start_time = time.time()
 7         func()
 8         end_time = time.time()
 9         print('函数运行时间:%s' % (end_time - start_time))
10     return get_time  # 将get_time函数名返回出去
11 index = outer(index)  # outer(index函数名)
12 # 左侧的变量名index指代是函数名get_time
13 index()

解决参数问题

 1 import time
 2 def index():
 3     time.sleep(3)
 4     print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!')
 5 def login(name):
 6     time.sleep(1)
 7     print('%s正在发牌'%name)
 8 def outer(func):  # func指向的是函数名login
 9     # func = login
10     def get_time(*args,**kwargs):
11         start_time = time.time()
12         func(*args,**kwargs)
13         end_time = time.time()
14         print('函数运行时间:%s' % (end_time - start_time))
15     return get_time  # 将get_time函数名返回出去
16 login = outer(login)
17 login('jason')
18 index = outer(index)
19 index()

解决返回值问题

 1 import time
 2 def index():
 3     time.sleep(3)
 4     print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!')
 5     return 'from index'
 6 def login(name):
 7     time.sleep(1)
 8     print('%s正在发牌'%name)
 9     return 'from login'
10 def outer(func):  # func指向的是函数名login
11     # func = login
12     def get_time(*args,**kwargs):
13         start_time = time.time()
14         res = func(*args,**kwargs)  # 接收被装饰函数的返回值
15         end_time = time.time()
16         print('函数运行时间:%s' % (end_time - start_time))
17         return res  # 执行完get_time之后返回被装饰函数执行之后的返回值
18     return get_time  # 将get_time函数名返回出去
19 # index = outer(index)
20 # res = index()
21 # print(res)
22 login = outer(login)
23 res1 = login('jason')
24 print(res1)

认证装饰器

 1 # 今天只需要掌握简单版本(每个都校验用户名和密码)
 2 # 记录用户状态的版本多花时间去练
 3 import time
 4 def index():
 5     time.sleep(1)
 6     print('百万大奖等你来拿 赶快加入我们吧!!!')
 7 def home():
 8     time.sleep(1)
 9     print('学学学 一天到晚就是学 卷死你们这些家伙')
10 def register():
11     time.sleep(1)
12     print('注册功能')
13 # 给index函数添加认证功能
14 """
15 在调用index之前需要用户输入用户名和密码
16     正确才可以调用
17     错误直接拒绝
18 """
19 # 定义一个用于记录用户是否登录的数据
20 is_login = {'is_login':False}
21 
22 
23 def login_auth(func):
24     def auth(*args,**kwargs):
25         # 1.1 先判断用户是否已经登录
26         if is_login.get('is_login'):
27             # 3.正常执行函数index
28             res = func(*args, **kwargs)
29             return res
30         # 1.先获取用户的用户名和密码
31         username = input('username>>>:').strip()
32         password = input('password>>>:').strip()
33         # 2.校验用户名和密码是否正确
34         if username == 'jason' and password == '123':
35             # 3.正常执行函数index
36             res = func(*args,**kwargs)
37             # 4.将记录用户登录状态的数据修改
38             is_login['is_login'] = True
39             return res
40         else:
41             print('用户名或密码错误 无法执行函数')
42     return auth
43 index = login_auth(index)
44 index()
45 home = login_auth(home)
46 home()
47 register = login_auth(register)
48 register()

装饰器固定模板

1 def outer(func):
2     def inner(*args, **kwargs):
3         print('执行函数之前可以添加的额外功能')
4         res = func(*args, **kwargs)  # 执行被装饰的函数
5         print('执行函数之后可以添加的额外功能')
6         return res  # 将被装饰函数执行之后的返回值返回
7     return inner

装饰器语法糖

 1 def outer(func):
 2     def inner(*args, **kwargs):
 3         print('执行函数之前可以添加的额外功能')
 4         res = func(*args, **kwargs)  # 执行被装饰的函数
 5         print('执行函数之后可以添加的额外功能')
 6         return res  # 将被装饰函数执行之后的返回值返回
 7     return inner
 8 @outer  # index = outer(index)
 9 def index(*args, **kwargs):
10     print('from index')
11 @outer  # home = outer(home)
12 def home():
13     print('from home')
14 """
15 装饰器语法糖是写规范
16     语法糖必须紧贴在被装饰对象的上方
17 装饰器语法糖内部原理
18     会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用
19 """

双层语法糖

 1 # 统计函数运行时间
 2 import time
 3 def get_time(func):
 4     def inner(*args, **kwargs):
 5         start_time = time.time()
 6         res = func(*args, **kwargs)  # 执行被装饰的函数
 7         end_time = time.time()
 8         print('函数执行时间:%s'%(end_time-start_time))
 9         return res  # 将被装饰函数执行之后的返回值返回
10     return inner
11 # 校验用户登录装饰
12 def login_auth(func):
13     def inner(*args, **kwargs):
14         # 1.先获取用户的用户名和密码
15         username = input('username>>>:').strip()
16         password = input('password>>>:').strip()
17         # 2.校验用户名和密码是否正确
18         if username == 'jason' and password == '123':
19             res = func(*args, **kwargs)  # 执行被装饰的函数
20             return res  # 将被装饰函数执行之后的返回值返回
21         print('用户名或密码错误 无权限执行')
22     return inner
23 @login_auth
24 @get_time
25 def index():
26     time.sleep(1)
27     print('from index')
28 index()

装饰器修复技术

 1 from functools import wraps
 2 def outer(func):
 3     @wraps(func)  # 修复技术就是为了让被装饰对象更加不容易被察觉装饰了
 4     def inner(*args, **kwargs):
 5         print('执行函数之前可以添加的额外功能')
 6         res = func(*args, **kwargs)  # 执行被装饰的函数
 7         print('执行函数之后可以添加的额外功能')
 8         return res  # 将被装饰函数执行之后的返回值返回
 9     return inner
10 
11 
12 @outer  # index = outer(index)
13 def index():
14     print('from index')
15 print(index)
16 help(index)
17 
18 def home():
19     """这是一个home函数"""
20     print('from home')
21 # help(index)
22 # help(home)
23 # print(index)
24 # help(len)

练习题

 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')

 

有参装饰器

 1 def outer(source_data):
 2     # source_data = 'file'
 3     def login_auth(func):
 4         def auth(*args,**kwargs):
 5             # 2.校验用户名和密码是否正确
 6             # 数据的校验方式可以切换多种
 7             if source_data == 'file':
 8                 # 从文件中获取用户数据并比对
 9                 print('file文件获取')
10             elif source_data == 'MySQL':
11                 # 从MySQL数据库中获取数据比对
12                 print('MySQL数据库获取')
13             elif source_data == 'postgreSQL':
14                 # 从postgreSQL数据库中获取数据对比
15                 print('postgreSQL数据库获取')
16             else:
17                 print('用户名或密码错误 无法执行函数')
18         return auth
19     return login_auth
20 
21 @outer('file')
22 def index():
23     print('from index')
24 @outer('MySQL')
25 def home():
26     print('from home')
27 
28 index()
29 home()

 

相关