叠加装饰器,

叠加装饰器

  • 在同一个被装饰对象中,添加多个装饰器,并执行。

    @装饰1
    @装饰2
    @装饰3
    def 被装饰对象():
        pass
    
  • 注意: 装饰器在调用被装饰对象时才会执行添加的功能。

    — 叠加装饰器:

    — 装饰的顺序: 由下到上装饰

    — 执行的顺序: 由上往下

  • 注意: 无论inner中出现任何判断,最后都要返回“调用后的被装饰对象” func(*args, **kwargs)
  • 装饰器模板
    def wrapper(func):
        def inner(*args, **kwargs):
            # 注册
            res = func(*args, **kwargs)
            # 登录
            return res
    
        return inner
    

    需求: 为被装饰对象,添加统计时间 与 登录认证功能

    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('
    ').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()
    
无参装饰器
  • 装饰在被装饰对象时,没有传参数的装饰器。

    这种没有参数的都属于无参装饰器:
    @wrapper1
    @wrapper2
    @wrapper3
    
有参装饰器
  • 装饰在被装饰对象时,有传参数的装饰器。

  • 有参装饰器:在某些时候,我们需要给用户的权限进行分类。

    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:(了解)
  • 是一个修复工具,修复的是被装饰对象的空间。

    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__
    
原文地址:https://www.cnblogs.com/lishuangjian/p/11853191.html