zoukankan      html  css  js  c++  java
  • Day 14:装饰器

    01 今日内容大纲

    1. 90,自我
    2. 调整自己,适当听取一些其他人的意见
    3. 承受压力的能力一定要有所提高

    02 昨日内容回顾

    1. 匿名函数:一句话函数,多与内置函数,列表推导式结合
    2. 内置函数:加key!!!! min,max,sorted,map,reduce,filter
    3. 闭包:
      • 内层函数对外层函数的非全局变量的使用
      • 一定要存在于嵌套函数中
      • 作用:保证数据安全,自由变量不会在内存中消失,而且全局还引用不到

    03 今日内容

    1. 开放封闭原则:
      # 装饰器:装饰,装修,房子可以住,如果装修,不影响你住,畏怯体验更加,让生活增加了很多功能:洗澡,看电视,沙发
      # 器:工具
      # 开放封闭原则:
      # 开放:对代码的拓展是完全开放的,更新地图,加新枪,等等
      # 封闭:对源码的修改是封闭的,闪躲用q.就是一个功能,一个函数,别人赤手空拳打你,机枪扫射你,扔雷....这些功能不会改变

    2. 装饰器初识:
      # 装饰器:完全遵循开放封闭原则.
      # 装饰器:在不改变原函数代码以及调用方式的前提下,为其增加新的功能
      # 装饰器就是一个函数

      • 版本一:写一些代码,测试一下index函数的执行效率
        import time
        def index():
        '''有很多代码'''
        time.sleep(2)#模拟网络延迟或代码效率
        print('欢迎登陆博客园首页')

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

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

        def timer(f):   #f = index
            def inner():
                start_time = time.time()
                f() #index()
                end_time = time.time()
                print(f'测试本函数的执行效率为{end_time - start_time}')
            return inner
        
        ret = timer(index) # ret = timer(index)=inner
        ret()   #inner()
        
      • 版本四:具体研究
        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
        # # timmer 装饰器
        def timmer(f):
        # f = index
        # f = <function index at 0x0000023BA3E8A268>
        def inner():
        start_time = time.time()
        f() #index()
        end_time = time.time()
        print(f'测试本函数的执行效率{end_time-start_time}')
        return inner

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

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

        @timmer # index = timmer(index)
        def index(name):
            '''有很多代码.....'''
            time.sleep(2) # 模拟的网络延迟或者代码效率
            print(f'欢迎{name}登录博客园首页')
            return 666
        ret = index('纳钦')  # inner('纳钦')
        print(ret)
        
        @timmer
        def dariy(name,age):
            '''有很多代码.....'''
            time.sleep(2) # 模拟的网络延迟或者代码效率
            print(f'欢迎{age}岁{name}登录日记页面')
        dariy('李舒淇',18)  # inner('李舒淇',18)
        
    3. 标准版装饰器代码:
      # 标准版
      def wrapper(f):
      def inner(args,**kwargs):
      '''添加额外的功能:执行被装饰函数之前的操作'''
      r = f(
      args,**kwargs)
      ''''添加额外的功能:执行被装饰函数之后的操作'''
      return r
      return inner

    4. 装饰器的应用:
      # 装饰器的应用:登录认证
      # 这周的周末作业:模拟博客园登录的作业。装饰器的认证功能。

      def login():
          pass
      def register():
          pass
      status_dict = {
          'username':None,
          'status': False
      }
      def auth(f):
          '''你的装饰器完成:访问被装饰函数之前,写一个三次登录认证的功能。
          登录成功:让其访问被装饰得函数,登录没有成功,不让访问。'''
          def inner(*args,**kwargs):
              '''访问函数之前的操作,功能'''
              if status_dict['status']:
                  r = f(*args,**kwargs)
                  '''访问函数之后的操作,功能'''
                  return r
              else:
                  username = input('请输入用户名').strip()
                  password = input('请输入密码').strip()
                  if username == '刘译蓬'and password =='daaipengge123':
                      status_dict['username'] = username
                      status_dict['status'] = True
                      r = f(*args,**kwargs)
                      return r
                  else:
                      print('登录失败')
          return inner
      @auth
      def article():
          print('欢迎访问文章页面')
      @auth
      def comment():
          print('欢迎访问评论页面')
      @auth
      def dariy():
          print('欢迎访问日记页面')
      
      article()
      comment()
      dariy()
      

    04 今日总结

    • 装饰器:完美的呈现了开放(拓展功能)封闭(被装饰函数)原则.装饰器的本质就是闭包(自由变量f)
    • def wrapper(f):
      	def inner(*args,**kwargs):
      		'''执行被装饰函数之前的操作,功能'''
      		r = f(*args,**kwargs)
      		'''执行被装饰函数之后的操作,功能'''
      		return r
      	return inner
      

    05 预习内容

  • 相关阅读:
    Sprinig.net 双向绑定 Bidirectional data binding and data model management 和 UpdatePanel
    Memcached是什么
    Spring.net 网络示例 codeproject
    jquery.modalbox.show 插件
    UVA 639 Don't Get Rooked
    UVA 539 The Settlers of Catan
    UVA 301 Transportation
    UVA 331 Mapping the Swaps
    UVA 216 Getting in Line
    UVA 10344 23 out of 5
  • 原文地址:https://www.cnblogs.com/Redbean1231/p/13381046.html
Copyright © 2011-2022 走看看