装饰器

  1. 开放封闭原则:

    1. 开放:对代码的拓展开放。
    2. 封闭:源码进行修改是封闭的。
    3. 装饰器:完全遵守开放封闭原则。
    4. 装饰器:在不改变原函数的代码以及调用方式的前提下,为其增加新的功能。
    5. 装饰器就是一个函数。
  2. 装饰器的初始:

    1. 版本一

      import time
      def index():
          '''有很多代码'''
          time.sleep(2)#模拟的网络延迟或者代码效率
          print('欢迎登陆')
          
      print(time.time())#格林威治时间
      start_time = time.time()
      index()
      end_time = time.time()
      print(end_time-start_time)
      
    2. 版本二利用函数,解决代码重复的问题

      import time
      def index():
          '''有很多代码'''
          time.sleep(2)
          print('欢迎登录博客园')
         
      def timmer(f):
          start_time = time.time()
          f()
          end_time = time.time()
          print(en_time-start_time)
      timmer(index)
      
      版本二还是有问题:原来index函数源码没有变化,给原函数添加一个新的功能,测试原函数的执行效率功能。
      不满足开放封闭原则,原函数的调用方式改变了
      
    3. 版本三:不能改变原函数的调用方式。

      import time
      def index():
          '''很多代码'''
          time.sleep(2)#模拟的网络延迟或者代码效率
          print('欢迎登录博客园首页')
          
      def timmer(f):
          def inner():
              start_time = time.time()
              f()
              end_time = time.time()
              print(end_time-start_time)
          return inner
      index = timmer(index) #inner  
      index() #inner()
      
      
    4. 版本四:具体研究

      import time
      def index():
          '''有很多代码'''
          time.sleep(2)
          print('欢迎登陆博客园首页')
          
      def timmer(f):
          def inner():
              start_time = time.time()
              f()
              end_time = time.time()
              print(end_time-start_time)
           return inner
      index = timmer(index)
      index()
      
    5. 版本五:python做了一个优化:提出了一个语法糖的概念。标准版的装饰器

      import time
      #timmer装饰器
      def timmer(f):
          def inner():
              start_time = time.time
              f()
              end_time = time.time
              print(end_time-start_time)
          return inner
      @timmer #index = timmer(index)
      def index():
          '''有很多代码'''
          time.sleep(0.6)#模拟的网络延迟或者代码效率
          print('欢迎登录博客园首页')
       index()
      
      
      
    6. 版本六:被装饰函数带返回值

      import time
      def timmer(f):
          f = index
          def inner():
              start_time = time.time()
              print(f'这个是f():{f()}')#index()
              r = f()
              end_time = time.time()
              print(end_time-start_time)
              return r
          return inner
      @timmer
      def index():
          '''有很多代码'''
          timer.sleep(0.6)#模拟的网络延迟或代码执行效率
          print('欢迎登陆博客园首页')
          return 666
      #加上装饰器不应该改变原函数的返回值,所以666 应该返回给我下面的ret,但是下面的这个ret实际接收的是inner函数的返回值,而666返回给的是装饰器里面的。
      #f()也就是r,我们现在要解决的问题就是将r给inner的返回值。
      ret = index()#inner
      print(ret)
      
    7. 版本七:被装饰函数带参数

      import time
      def timmer(f):
          def inner(*args,**kwargs):
              #函数的定义:*聚合 args = ('happe.豪',19)
              start_time = time.time()
              r = f(*args,**kwargs)
              #函数的执行:*打散:f(*args)-->f(*('happe.豪',19))-->f('happe.豪',19)
              end_time = time.time()
              print(end_time-start_time)
              return r
          return inner
      @timmer
      def index(name,age):
          '''有很多代码'''
          time.sleep(0.6)#模拟的网络延迟或者代码效率
          print(f'欢迎{age}岁{name}登陆博客园首页')
      
    8. 标准版装饰器

      #标准版装饰器
      def wrapper(f):
          def inner(*args,**kwargs):
              '''添加额外的功能:执行被装饰函数之前的操作'''
              ret = f(*args,**kwargs)
              '''添加额外的功能:执行被装饰函数之后的操作'''
              return ret
          return inner
      
原文地址:https://www.cnblogs.com/wang-xing-hao/p/10877961.html