装饰器

装饰器
1.什么是装饰器?
  装饰器指的是为被装饰对象添加新功能的工具
  装饰器本身可以是任意可调用对象
  被装饰对象本身也可以是任意可调用对象
2.为何要用 装饰器
  开放封闭原则:对修改封闭,对扩展开放
  装饰器的实现原则:
    1.不能修改被装饰对象的源代码
    2.不能修改被装饰对象的调用方式
  装饰器的目的:
    就是在遵循原则1和2的前提下为被装饰对象添加新功能
3.如何使用
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
  index()
  #统计运行时间
  思路1
  import time
  def index():
    start=time.time()
    time.sleep(1)
    print('welcome to index page')
    stop=time.time()
    print('run time is %s'%(stop - start))
  index()
  修改了源代码

  思路2
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
  start=time.time()
  index()
  stop=time.time()
  print('run time is %s' %(stop - start))
  不能重复使用,下面我们将它写在一个函数里面

  思路3
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
  def wrapper():
    start=time.time()
    index()
    stop=time.time()
    print('run time is %s' %(stop - start))
  wrapper()
  可以重复调用但是写死了,只能修饰index,下面我们要将其写活,将index换成func

  思路4:
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
  def wrapper():
    start=time.time()
    func()
    stop=time.time()
    print('run time is %s' %(stop - start))
  wrapper()
  函数体需要外部传进来参数,两种解决方案 1.直接传参 2.闭包函数

  直接传参:
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
  def wrapper(func):
    start=time.time()
    func() #index()
    stop=time.time()
    print('run time is %s' %(stop - start))
  wrapper(index)
  本来使用index()调用的,这个直接改变了人家的调用方式违反了开放封闭原则

  闭包函数:
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
  def timer(func):
    #func=最原始index的内存地址
    def wrapper():
      start=time.time()
      func() #func=最原始index的内存地址
      stop=time.time()
      print('run time is %s' %(stop - start))
    return wrapper
  index=timer(index) #翻译一下:index=(timer(最原始index的内存地址)) #index=wrapper的内存地址
  index() #wrappper的内存地址()

  思路5:完善这个装饰器
  如果有返回值:
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
    return 1234
  def timer(func):
    def wrapper():
      start=time.time()
      res=func()
      stop=time.time()
      print('run time is %s' %(stop - start))
      return res
    return wrapper
  index=timer(index)
  res=index()
  print(res)

如果还有其他函数被装饰:
  import time
  def index():
    time.sleep(1)
    print('welcome to index page')
    return 1234
  def home(name):
    time.sleep(1)
    print('welcome %s to home page' %name)
  def timer(func):
    def wrapper(*args,**kwargs):
      start=time.time()
      res=func(*args,**kwargs)
      stop=time.time()
      print('run time is %s' %(stop - start))
      return res
    return wrapper
  index=timer(index)
  index()
  home=timer(home)
  home('egon')

  思路6:语法糖 在被装饰对象正上方单独一行写上@装饰器的名字
  import time
  def timer(func):
    def wrapper(*args,**kwargs):
      start=time.time()
      res=func(*args,**kwargs)
      stop=time.time()
      print('run time is %s' %(stop - start))
      return res
    return wrapper
  @timer 作用:#index=timer(index) #翻译一下:index=(timer(最原始index的内存地址)) #index=wrapper的内存地址
  def index():
    time.sleep(1)
    print('welcome to index page')
    return 1234
  @timer
  def home(name):
    time.sleep(1)
    print('welcome %s to home page' %name)
  index()
  home('egon')

  装饰器模板:
  def outter(func):
    def wrapper(*args,**kwargs):
    res=func(*args,**kwargs)
    return res
  return wrapper


原文地址:https://www.cnblogs.com/lizeqian1994/p/10040019.html