Superposition decorator
In the same object to be decorated, add multiple decorators, and executed.
@装饰1 @装饰2 @装饰3 def 被装饰对象(): pass
Note: decorator in the calling function will be performed when the added decorative objects.
- overlay decorator:
- Decorative sequence: from the bottom to the decorative
- The order of execution: from top to bottom
Note: Regardless of any judgment appeared in the inner, the last to be returned "after the call is decorative objects" func (* args, ** kwargs)
Decorative template
def wrapper(func): def inner(*args, **kwargs): # 注册 res = func(*args, **kwargs) # 登录 return res return inner
Requirements: to be decorative objects, add time statistics and login authentication function
import time user_info = { 'user': None } # 全局变量 #登陆功能 def login(): # 判断用户没有登陆时执行 # 登录功能 username = input('请输入账号:').strip() password = input('请输密码:').strip() with open('auth.txt', 'r', encoding='utf-8')as f: for line in f: print(line) name, pwd = line.strip('\n').split(',') # [li,123] if username == name and password == pwd: print('登陆成功') user_info['user'] = username return True else: print('登陆失败!') return False #登陆认证装饰器 def login_auth(func): #func---> download_movie def inner1(*args, **kwargs): ''' 注意:无论inner中出现任何判断, 最后都要返回“调用后的被装饰对象”func(*args, **kwargs) ''' # 登陆认证 if user_info.get('user'): # res = func(*args, **kwargs) res = func(*args, **kwargs) return res else: flag = login() # 添加用户是否登陆判断 if flag: res = func(*args, **kwargs) return res else: login() return func(*args, **kwargs) return inner1 # 统计时间装饰器 def tine_record(func): def inner2(*args, **kwargs): print('开始统计...') start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print(f'消耗时间为:{end_time - start_time}') return res return inner2 #下载电影功能 @tine_record # inner2 = time_record(inner1地址) @login_auth #inner1 = login_auth(download_movie) def download_movie(): print('正在下载电影...') time.sleep(2) print('下载电影完成...') return 'sdsd.mp4' download_movie()
No reference decorator
When the object to be decorated decoration, it did not pass the parameters decorator.
这种没有参数的都属于无参装饰器: @wrapper1 @wrapper2 @wrapper3
There are parameters decorator
When the object to be decorated decoration with parameters passed decorator.
There are parameters decorator: At some point, we need to classify the user's permission.
def user_auth(user_role): def wrapper(func): def inner(*args, **kwargs): if user_role == 'SVIP': # 添加超级用户的功能 res = func(*args, **kwargs) return res elif user_role == '普通用户': print('普通用户') # 添加普通用户的功能 res = func(*args, **kwargs) return res return inner return wrapper # 被装饰对象 # @user_auth('SVIP') wrapper = user_auth('普通用户') @wrapper #《--- 返回结果(wrapper) <---user_auth() def index(): pass index()
wraps :( understand)
It is a repair tool to repair the space is decorated objects.
from functools import wraps def wrapper(func): @wraps(func) # 修改名称空间: inner ---》 func def inner(*args, **kwargs): ''' 此处是装饰器的注释 :param func: :return: ''' res = func(*args, **kwargs) return res return inner # ---》 func @wrapper def index(): ''' 此处是index函数的注释 :return: ''' pass print(index) # 函数对象 # 函数对象.__doc__: 查看函数内部的注释 print(index.__doc__) # inner.__doc__