装饰器

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的内存地址()

原文地址:https://www.cnblogs.com/gongcheng-/p/9714460.html