zoukankan      html  css  js  c++  java
  • 叠加装饰器,

    叠加装饰器

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

      @装饰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__
      
  • 相关阅读:
    mysql面试题
    Zookeeper与Kafka基础概念和原理
    Docker资源限制
    企业级仓库harbor搭建
    基于容器制作镜像
    docker基础学习(一)
    docker往阿里云推镜像和打包镜像
    Dockfile制作镜像
    算法Sedgewick第四版-第1章基础-006一封装输出(文件)
    算法Sedgewick第四版-第1章基础-005一封装输入(可以文件,jar包里的文件或网址)
  • 原文地址:https://www.cnblogs.com/lishuangjian/p/11853191.html
Copyright © 2011-2022 走看看