• 装饰器


    1 什么是装饰器

      器=>工具

      装饰=>指的是为被装饰对象添加新功能

      装饰器本身可以是任意可调用的对象=>函数

      被装饰的对象也可以是任意可调用的对象=>函数

      目标:写一个函数来为另一个函数添加新功能

    2 为何要用装饰器

      开放封闭原则:软件一旦上线就应该对修改封闭,对拓展开放

        对修改封闭:

          1.不能修改功能的源代码

          2.也不能修改功能的调用方式

        对拓展开放

          可以为原有功能添加新功能

      装饰器就是要在不修改功能源代码以及调用方式的前提下为原有功能添加新功能

    3.如何用装饰器

    函数无返回值

    import time

    def index():

      print('welcome to index page;)

      time.sleep(3)

    def outter(func):

      # func=最原始那个index的内存地址

      def wrapper ():

        start=time.time()

        func()#最原始那个index的内存地址()

        stop=time.time()

        print('run time is %s'%(stop-start))

      return wrapper

    index=outter(index) #index=outter(最原始那个index的内存地址) #index=wrapper函数的内存地址

    index() #wraper()

    函数有返回值'

    import time

    def index():

      print('welcome to index page')

      time,sleep(3)

      return 123

    def outter(func):

      # func=最原始那个index的内存地址

      def wrapper():

        start=time.time()

        res=func() 

        stop=time.time()

        print('run time is %s'%(stop-start))

        return res

      return wrapper

    index=outter(index) #index=outter(最原始那个index的内存)

    res=index() 

    print(res)

    import time

    def index():

      print('welcome to index page')

      time.sleep(3)

      return 123

    def home(name)

      print('welcom %s to home page'%name)

      time.sleep(1)

    def outter(func):

      #func=最原始那个home的内存地址

      def wrapper(*args,**kwargs)

        start=time.time()

        res=func(*args,**kwargs)

        stop=time.time()

        print('run time is %'%(stop-start))

        return res

      return wrapper

    index=outter(index) #index=outter(最原始那个index的内地址) #index=wrapper函数的内地址
    home=outter(home) #index=outter(最原始那个home的内地址) #home=wrapper函数的内地址

    home('egon')

    index()#wrapper()

    @装饰器的名字:要在被装饰对象正上方单独一行写上

    import time

    def timmer(func): # func=最原始那个home的内存地址

      def wrapper(*args,**kwargs)

        start=time.time()

        res=func(*args,**kwargs)

        stop=time.time()

        print('run time is %s"%(stop-start))

        return res

      wrapper.__doc__=func.__doc__

      wrapper.__name__=func.__name__

      return wrapper

    @timmer #index=timmer(index) #index=timmer(最原始那个index的内存地址)

    def index():

      """这是index功能"""

      print('welcom to index page')

      time.sleep(3)

      return 123

    @time #home=timmer(home) #index=timmer(最原始那个home的内存地址)#index=wrapper函数的内存地址

    def index:

      """这是index"""

      print('welcom to index page')
      time.sleep(3)  

      return 123

    @timmer

    def home(name):

      """这是home功能"""

      print('welcome %s to home page' %name)

      time.sleep(1)

    print(help(index))

    print(index.__name__)

    无参装饰器的模板

    def outter(func):

      def wrapper(*args,**kwrgs):

        res=func(*args,**kwargs)

        return res

      return wrapper

    import time

    user_info={'current_user':None}

    def auth(func):
      def wrapper(*args,**kwargs):
        if user_info['current_user'] is not None:
          res=func(*args,**kwargs)
          return res
          inp_user=input('username>>>: ').strip()
          inp_pwd=input('password>>>: ').strip()
          if inp_user == 'egon' and inp_pwd == '123':
            # 记录登录状态
            user_info['current_user']=inp_user

            print('login successful')
            res=func(*args,**kwargs)
            return res
          else:
            print('user or password error')
            return wrapper

    @auth
    def index():
      """这是index功能"""
      print('welcome to index page')
      time.sleep(2)
    return 123

    @auth
    def home(name):
      """这是home功能"""
      print('welcome %s to home page' %name)
      time.sleep(1)

    # index()
    # home('egon')


    # 有参装饰器
    def outter2(xxx,yyy):
      def outter(func):
        def wrapper(*args,**kwargs):
          res=func(*args,**kwargs)
          print(xxx)
          print(yyy)
          return res
        return wrapper
      return outter

    import time

    user_info={'current_user':None}

    def auth2(engine='file'):
      def auth(func):
        def wrapper(*args,**kwargs):
          if user_info['current_user'] is not None:
            res=func(*args,**kwargs)
            return res
          inp_user=input('username>>>: ').strip()
          inp_pwd=input('password>>>: ').strip()

          if engine == 'file':
            print('基于文件的认证')
            if inp_user == 'egon' and inp_pwd == '123':
              # 记录登录状态
              user_info['current_user']=inp_user

              print('login successful')
              res=func(*args,**kwargs)
              return res
            else:
              print('user or password error')
            elif engine == 'mysql':
              print('基于mysql数据的认证')
            elif engine == 'ldap':
              print('基于ldap的认证')
            else:
              print('无法识别认证源')
        return wrapper
      return auth

    @auth2(engine='mysql') # @auth ===> index=auth(最原始那个index的内存地址)===》index=wrapper
    def index():
      """这是index功能"""
      print('welcome to index page')
      time.sleep(2)
      return 123

    @auth2(engine='file')
    def home(name):
      """这是home功能"""
      print('welcome %s to home page' %name)
      time.sleep(1)

    index() #wrapper()
    home('egon')

    4.叠加多个装饰器

    加载装饰器就是将原函数名偷梁换柱成装饰器最内层那个warpper函数

    在加载完毕后,调用原函数其实就是在调用warpper函数

    当一个呗装饰的对象同时叠加多个装饰器时

    装饰器的加载顺序是:自下而上

    装饰器内wrapper函数的执行顺序是:自上而下

    import time

    def timmer(func):#func=wrapper2的内容地址

      def wrapperl(*args,**kwargs):

        print('=====>wrapper:1运行了')

        start=time.time()

         res=func(*args,**kwargs)

         stop=time.time()

        print('run time is %s'%(stop-start))

        return res

      return wrappoer1

    def auth(engine='file'):

      def xxx(func): # func = 最原始那个index的内存

         def wrapper2(*args,**kwargs):

          print('===========>wrapper2运行了')

          name=input('username>>>:').strip()

          pwd=input('password>>:').strip()

          if engine=='file':

             print('基与文件的认证')

           if engine=='egon' and pwd =='123':

            print('login sunccessfull')

             res = func(*args,**kwargs)

          return res

          elif engine =='mysql':

             print('基于mysql的认证')

           elif engine =='ldap':

            print('基于ldap的认证')

           else:

            print('错误的认证源')

           return wrapper2

          return xxx

    @timmer #iindex=timmer(wrapper2的内存地址) #index=wrapper1的内存地址

    @auth(engine='file') #@xxx #index=xxx(最原始那个index的内存地址) #index=wrapper的内存地址

    def index():

    print('welcom to index page')

    time.sleep(2)

    index() #wrapper1的内存地址()

  • 相关阅读:
    洛谷 P1037 产生数
    【bzoj】 1070: [SCOI2007]修车
    【bzoj】 1066: [SCOI2007]蜥蜴 (网络流)
    开发环境搭建
    数据库设计
    sql优化实例(用左连接)
    泛型T和通配符?的区别
    Nginx配置优化
    Tomcat优化
    Nginx反向代理配置
  • 原文地址:https://www.cnblogs.com/gongcheng-/p/9714460.html
Copyright © 2020-2023  润新知