装饰器叠加和有参装饰器

叠加多个装饰器

  • 叠加多个装饰器

    1. 加载顺序(outer函数的调用顺序):自下而上

    2. 执行顺序(wrapper函数的调用顺序):从上到下

      # 叠加多个装饰器
      # 1. 加载顺序(outter函数的调用顺序):自下而上
      # 2. 执行顺序(wrapper函数的执行顺序):自上而下
      ​
      ​
      def outter1(func1): #func1=wrapper2的内存地址
          print('加载了outter1')
          def wrapper1(*args,**kwargs):
              print('执行了wrapper1')
              res1=func1(*args,**kwargs)
              return res1
          return wrapper1
      ​
      def outter2(func2): #func2=wrapper3的内存地址
          print('加载了outter2')
          def wrapper2(*args,**kwargs):
              print('执行了wrapper2')
              res2=func2(*args,**kwargs)
              return res2
          return wrapper2
      ​
      def outter3(func3): # func3=最原始的那个index的内存地址
          print('加载了outter3')
          def wrapper3(*args,**kwargs):
              print('执行了wrapper3')
              res3=func3(*args,**kwargs)
              return res3
          return wrapper3
      ​
      ​
      ​
      @outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
      @outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
      @outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
      def index():
          print('from index')
      ​
      print('======================================================')
      index()

有参装饰器

  • 应用场景:当装饰器函数内除要传入被装饰对象外还要传入其他参数时,就需要用到有参装饰器。

    # 实现一个基于函数验证的装饰器,其后台数据存 放方式有多种
    from functools import wraps
    tag = 0
    ​
    def auth(engin):  # 函数用到除func以外函数,故再套一层函数
        def outer(func):
            @wraps(func)  # wraps函数,相当是一个装饰器将原始被装饰对象的name、和注释传给了wrapper函数
            def wrapper(*args,**kwargs):
                global tag  # 全局声明,要使用全局中的名字
                if tag:  # tag 为True 时,即不再需要验证,通过改变全局变量的方式更改tag的值
                    res = func(*args, **kwargs)
                    return res
                name = input('username:').strip()
                pwd = input('password:').strip()
                if engin =='file':
                    if name == 'jason' and pwd == '123':
                        print('login successful !')
                        res = func(*args, **kwargs)
                        tag = 1  # 将tag变为True
                        return res
                    else:
                        print('name or password !')
                elif engin =='mysql':
                    print('执行MySQL认证功能')
                elif engin == 'ldap'
                    print('执行ldap认证功能')
                else:
                    print('输入有误')
            return wrapper
        return outer
        
        
    @auth('file')  # engine=file,@outer   # outer = outer(welcome)    # welcome=wrapper
    def welcome():
        print('welcome to XXX bank !')
            
    @auth('file')
    def check():
        print('查看余额')
原文地址:https://www.cnblogs.com/liusijun113/p/10942324.html