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 预习内容

  • 相关阅读:
    Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[2]
    Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]
    进程和线程
    Linux 技巧:让进程在后台可靠运行的几种方法
    Linux 网络命令必知必会之 tcpdump,一份完整的抓包指南请查收!
    这些好用的 Chrome 插件,提升你的工作效率
    golang学习笔记-go mod的使用
    性能监控和分析工具---nmon
    Jenkins
    程序员画图工具总结
  • 原文地址:https://www.cnblogs.com/Redbean1231/p/13381046.html
Copyright © 2011-2022 走看看