zoukankan      html  css  js  c++  java
  • 闭包函数与装饰器

    闭包函数与装饰器

    一、什么是闭包函数

    ​ 闭:封闭

    ​ 包:包裹

    ​ 闭包函数必须在函数内部定义

    ​ 闭包函数可以引用外层函数的名字

    ​ 闭包函数就是函数嵌套,函数对象,名称空间与作用域的结合体

    二、闭包函数的传参

    • 直接传参

      def fun(x):
          print(x)
          
      func(1000)
      
    • 通过闭包函数传参

      def outer(num):
          def inner():
              print(num)
          return inner
      
      func = outer(100)#inner地址
      func()
      

    三、装饰器及装饰器语法糖

    • 什么是装饰器

      装饰:装饰,修饰

      器:工具

    • 装饰器必须要遵循的‘开放封闭原则’

      开放:对函数功能的添加是开放的

      封闭:对函数功能的修改是封闭的

    • 装饰器的作用

      在不修改被装饰对象源代码与调用方式的前提下,添加新的功能

      被修饰对象:需要添加功能的函数

      装饰对象:添加功能函数

    • 应用

      统计时间

      登录认证

      可以解决冗余代码,提高代码可扩展性

    • 小实例结合time包

      import time
      # 被修饰函数
      def download_movie():#download_movie函数名
          print('开始下载电影')
          time.sleep(3)#模拟下载时间
          print('电影下载成功')
      
      start_time = time.time()
      download_movie()
      end_time = time.time()
      print(f'电影下载时间:{end_time - start_time}')
      >>>开始下载电影
      电影下载成功
      电影下载时间:3.0007519721984863
      
      #装饰器即装饰函数
      def time_record(func):#time_record装饰器的函数名,func形参,用来接收实参
          def inner():#内部函数名
              start_time = time.time()
              func()#执行接收到的函数
              end_time = time.time()
              print(f'电影下载时间:{end_time - start_time}')
          return inner#调用time_record这个函数返回inner的内存地址
      
      
      #print(time_record(download_movie))#time_record(download_movie)是一个内存地址
      download_movie = time_record(download_movie)
      download_movie()
      >>>开始下载电影
      电影下载成功
      电影下载时间:3.000049352645874
      开始下载电影
      电影下载成功
      电影下载时间:3.00085186958313
      
      #1、被修饰对象有返回值
      import time
      
      def download_movie():
          print('开始下载电影')
          time.sleep(3)#模拟下载时间
          print('电影下载成功')
      
          return '小泽.mp4'#调用函数返回'小泽.mp4'
      
      def time_record(func):#func<---download_movie
          def inner():
              start_time = time.time()
              res = func()#res = '小泽.mp4'
              # print(res)#res字符串
              end_time = time.time()
              print(f'电影下载时间:{end_time - start_time}')
              return res#调用函数inner返回res
          # print(inner())
          return inner#调用函数time_record返回inner,此时才是地址
      
      # print(time_record(download_movie))#inner地址
      download_movie = time_record(download_movie)
      download_movie()
      >>>开始下载电影
      电影下载成功
      电影下载时间:3.0000083446502686
      
      #2、被修饰对象有参数
      import time
      
      def download_movie(url):#url用来接收参数
          print('开始下载电影')
          time.sleep(3)#模拟下载时间
          print('电影下载成功')
          return '小泽.mp4'#返回'小泽.mp4'
      
      def time_record(func):#func用来接收被修饰函数func<---download_movie
          def inner(url):#url接收参数
              start_time = time.time()
              res = func(url)#func(url)<----download_movie(url)
              end_time = time.time()
              print(f'电影下载时间:{end_time - start_time}')
              return res#把res即(download_movie(url))---->inner
          return inner#(download_movie(url))---->time_record
      
      download_movie = time_record(download_movie)
      download_movie('https://www.jd.com/')
      >>>开始下载电影
      电影下载成功
      电影下载时间:3.0002450942993164
      
      #3、有多个参数
      import time
      
      def download_movie(*args, **kwargs):
          print('开始下载电影')
          time.sleep(3)#模拟下载时间
          print('电影下载成功')
          return '小泽.mp4'#把'小泽.mp4'
      
      def time_rcod(func):
          def inner(*args, **kwargs):
              start_time = time.time()
              res = func(*args, **kwargs)
              end_time = time.time()
              print(f'电影下载时间:{end_time - start_time}')
              return res
          return inner
      download_movie = time_rcod(download_movie)
      download_movie('https://www.baidu.com/')
      >>>开始下载电影
      电影下载成功
      电影下载时间:3.000089168548584
      
      
    • 装饰器模板

      def wrapper(func):
          def inner(*args,**kwargs):
              #添加功能
      
              res = func(*args,**kwargs)
      
              #添加功能
      
              return res
      
          return inner
      
      def func1():
          pass
      
      func1 = wrapper(func1)#func1被修饰函数,wrapper修饰函数
      func1()
      
    • 装饰器语法糖

      装饰器的语法糖是属于装饰器的

      @:装饰器的语法糖

      注意:在使用装饰器的语法糖时,装饰器必须定义在被装饰函数前

      # 统计函数执行时间装饰器
      def wrapper(func):  # 被装饰对象
          def inner(*args, **kwargs):  # 被装饰对象的参数
              # 调用前增加新功能
              start_time = time.time()
              # 调用被装饰对象,并接收返回值
              res = func(*args, **kwargs)
      
              # 调用后添加新功能
              end_time = time.time()
              print(end_time - start_time)
      
              return res
          return inner
      
      
      # func函数需要执行3秒
      
      # 无参装饰器
      # 使用装饰器
      @wrapper  # wrapper(func)  ---> func
      def func():
      
          time.sleep(3)
      
      
  • 相关阅读:
    Linux命令 tr
    Linux命令 xargs
    Python 文件读写 文件和路径
    Python 正则表达式 匹配任意字符
    Python 正则表达式 贪心匹配和非贪心匹配
    Python 正则表达式 匹配次数
    Python 正则表达式 利用括号分组
    Python 正则表达式 search vs match
    【转-整理】 SQL2008 提示评估期已过的解决方法
    Java http接口进阶——自我理解为接口框架形式
  • 原文地址:https://www.cnblogs.com/yafeng666/p/11843169.html
Copyright © 2011-2022 走看看