• 装饰器 14


    1. 开放封闭原则:

      开放:对源码的拓展开放的,更新地图,游戏中增加新的枪械,等等。
      封闭:对源码的修改是封闭的。
      
      装饰器:在不改变原函数代码以及调用方式的前提下,为其增加新的功能。
      装饰器就是一个函数。
      装饰器:完全遵循开放封闭原则。
      
    2. 装饰器的初识:

      • 版本一: 写一些代码测试一下index函数的执行效率。

        import time
        # def index():
        #     '''有很多代码.....'''
        #     time.sleep(2) # 模拟的网络延迟或者代码效率
        #     print('欢迎登录博客园首页')
        #
        # def dariy():
        #     '''有很多代码.....'''
        #     time.sleep(3) # 模拟的网络延迟或者代码效率
        #     print('欢迎登录日记页面')
        
        # print(time.time())  # 格林威治时间。
        # print(111)
        # time.sleep(3)
        # print(222)
        # 版本一有问题: 如果测试别人的代码,必须重新赋值粘贴。
        # start_time = time.time()
        # index()
        # end_time = time.time()
        # print(end_time-start_time)
        #
        # start_time = time.time()
        # dariy()
        # end_time = time.time()
        # print(end_time-start_time)
        #
        #
        # start_time = time.time()
        # # dariy()
        # end_time = time.time()
        # print(end_time-start_time)
        
      • 版本二:利用函数,解决代码重复使用的问题。

        import time
        def index():
            '''有很多代码.....'''
            time.sleep(2) # 模拟的网络延迟或者代码效率
            print('欢迎登录博客园首页')
        # index()
        def dariy():
            '''有很多代码.....'''
            time.sleep(3) # 模拟的网络延迟或者代码效率
            print('欢迎登录日记页面')
        
        def timmer(f):  # f= index
            start_time = time.time()
            f()  # index()
            end_time = time.time()
            print(f'测试本函数的执行效率{end_time-start_time}')
        timmer(index)
        
        版本二还是有问题: 原来index函数源码没有变化,给原函数添加了一个新的功能测试原函数的执行效率的功能。
        满足开放封闭原则么?原函数的调用方式改变了。
        
      • 版本三:不能改变原函数的调用方式。

        # import time
        # def index():
        #     '''有很多代码.....'''
        #     time.sleep(2) # 模拟的网络延迟或者代码效率
        #     print('欢迎登录博客园首页')
        #
        
        def time(f):
        	def inner():
        	start_time = time.time()
        	f()
        	end_time = time.time()
        	print(f'测试本函数的执行效率{end_time - start_time}')
        # timmer(index)  # index()
        # ret = timmer(index)  # inner
        # ret()  # inner()
        # index = timmer(index)  # inner (funciton inner123)
        # index()  # inner()
        # def func():
        #     print('in func')
        #
        # def func1():
        #     print('in func1')
        #
        # # func()
        # # func1()
        # func()
        # func = 666
        # func(0)
        
    • 版本四:具体研究

      import time
      def index():
          '''有很多代码.....'''
          time.sleep(2) # 模拟的网络延迟或者代码效率
          print('欢迎登录博客园首页')
      
      def timmer(f):
          f = index
          # f = <function index at 0x0000023BA3E8A268>
          def inner():
              start_time = time.time()
              f()
              end_time = time.time()
              print(f'测试本函数的执行效率{end_time-start_time}')
          return inner
      
      index = timmer(index)
      index()
      
    • 版本五:python做了一个优化:提出了一个语法糖的概念。标准版的装饰器。

      import time
      #time 装饰器
      def timmer(f)
      	def inner():
      		start_time = time.time()
      		f()
      		end_time = time.time()
      		print(f'测试函数的执行效率{end_time - star_time}')
      	return inner
      	
      def index():
          '''有很多代码.....'''
          time.sleep(0.6) # 模拟的网络延迟或者代码效率
          print('欢迎登录博客园首页')
          return 666
      ret = index()
      print(ret)
      
      def dariy():
          '''有很多代码.....'''
          time.sleep(3) # 模拟的网络延迟或者代码效率
          print('欢迎登录日记页面')
      dariy()
      # index = timmer(index)
      # index()
      # dariy = timmer(dariy)  @timmer
      dariy()
      
    • 版本六:被装饰函数带返回值

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

      def timmer(f):
          # f = index
          def inner(*args,**kwargs)
          #函数的定义;*聚合 args = ('holting',20)
           start_time = time.time()
              # print(f'这是个f():{f()}!!!') # index()
              r = f(*args,**kwargs)
              # 函数的执行:* 打散:f(*args) -->f('holting',20)--> f('holting',20)
              end_time = time.time()
              print(f'测试本函数的执行效率{end_time-start_time}')
              return r
          return inner
      
      @timmer # index = timmer(index)
      def index(name):
          '''有很多代码.....'''
          time.sleep(0.6) # 模拟的网络延迟或者代码效率
          print(f'欢迎{name}登录博客园首页')
          return 666
      index('纳钦')  # inner('纳钦')
      
      @timmer
      def dariy(name,age):
          '''有很多代码.....'''
          time.sleep(0.5) # 模拟的网络延迟或者代码效率
          print(f'欢迎{age}岁{name}登录日记页面')
      dariy('holting',20) 
      
      标准版的装饰器:
      def wrapper(f):
      	def(*args,**kwargs):
      		'''添加额外的功能:执行被装饰函数之前的操作'''
      		ret =f(*args,**kwargs)
      		''''添加额外的功能:执行被装饰函数之后的操作'''
      		return ret
      	return inner
      
      
    1. 装饰器的应用

      # 装饰器的应用:登录认证
      # 这周的周末作业:模拟博客园登录的作业。装饰器的认证功能。
      
      def login():
          pass
      
      
      def register():
          pass
      
      
      status_dict = {
          'username': None,
          'status': False,
      }
      
      def auth(f):
          '''
          你的装饰器完成:访问被装饰函数之前,写一个三次登录认证的功能。
          登录成功:让其访问被装饰得函数,登录没有成功,不让访问。
          :param f:
          :return:
          '''
          def inner(*args,**kwargs):
              '''访问函数之前的操作,功能'''
              if status_dict['status']:
                  ret = f(*args,**kwargs)
                  '''访问函数之后的操作,功能'''
                  return ret
              else:
              	login()
      @auth  # article = auth(article)
      def article():
          print('欢迎访问文章页面')
      @auth
      def comment():
          print('欢迎访问评论页面')
      @auth
      def dariy():
          print('欢迎访问日记页面')
      
      article()  # inner()
      comment()  #inner()
      dariy()
      
      
  • 相关阅读:
    20200302 数据分析之numpy以及Jupyter
    20200228 scrapy高级使用及分布式
    20200226 请求库selenium
    20200224 爬虫-requests模块
    0219 请求上下文解析与g对象
    Matlab矩阵求导和求梯度有什么不同
    矩阵中范数的处理方式
    如何巧妙地使用递归
    遗传算法求最短路径
    nparray的维度和取值方式
  • 原文地址:https://www.cnblogs.com/zhaoxinblog/p/13258017.html
Copyright © 2020-2023  润新知