经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
闭包函数与装饰器
来源:cnblogs  作者:亚峰牛皮  时间:2019/11/13 8:58:39  对本文有异议

闭包函数与装饰器

一、什么是闭包函数

? 闭:封闭

? 包:包裹

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

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

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

二、闭包函数的传参

  • 直接传参

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

    1. def outer(num):
    2. def inner():
    3. print(num)
    4. return inner
    5. func = outer(100)#inner地址
    6. func()

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

  • 什么是装饰器

    装饰:装饰,修饰

    器:工具

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

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

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

  • 装饰器的作用

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

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

    装饰对象:添加功能函数

  • 应用

    统计时间

    登录认证

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

  • 小实例结合time包

    1. import time
    2. # 被修饰函数
    3. def download_movie():#download_movie函数名
    4. print('开始下载电影')
    5. time.sleep(3)#模拟下载时间
    6. print('电影下载成功')
    7. start_time = time.time()
    8. download_movie()
    9. end_time = time.time()
    10. print(f'电影下载时间:{end_time - start_time}')
    11. >>>开始下载电影
    12. 电影下载成功
    13. 电影下载时间:3.0007519721984863
    14. #装饰器即装饰函数
    15. def time_record(func):#time_record装饰器的函数名,func形参,用来接收实参
    16. def inner():#内部函数名
    17. start_time = time.time()
    18. func()#执行接收到的函数
    19. end_time = time.time()
    20. print(f'电影下载时间:{end_time - start_time}')
    21. return inner#调用time_record这个函数返回inner的内存地址
    22. #print(time_record(download_movie))#time_record(download_movie)是一个内存地址
    23. download_movie = time_record(download_movie)
    24. download_movie()
    25. >>>开始下载电影
    26. 电影下载成功
    27. 电影下载时间:3.000049352645874
    28. 开始下载电影
    29. 电影下载成功
    30. 电影下载时间:3.00085186958313
    31. #1、被修饰对象有返回值
    32. import time
    33. def download_movie():
    34. print('开始下载电影')
    35. time.sleep(3)#模拟下载时间
    36. print('电影下载成功')
    37. return '小泽.mp4'#调用函数返回'小泽.mp4'
    38. def time_record(func):#func<---download_movie
    39. def inner():
    40. start_time = time.time()
    41. res = func()#res = '小泽.mp4'
    42. # print(res)#res字符串
    43. end_time = time.time()
    44. print(f'电影下载时间:{end_time - start_time}')
    45. return res#调用函数inner返回res
    46. # print(inner())
    47. return inner#调用函数time_record返回inner,此时才是地址
    48. # print(time_record(download_movie))#inner地址
    49. download_movie = time_record(download_movie)
    50. download_movie()
    51. >>>开始下载电影
    52. 电影下载成功
    53. 电影下载时间:3.0000083446502686
    54. #2、被修饰对象有参数
    55. import time
    56. def download_movie(url):#url用来接收参数
    57. print('开始下载电影')
    58. time.sleep(3)#模拟下载时间
    59. print('电影下载成功')
    60. return '小泽.mp4'#返回'小泽.mp4'
    61. def time_record(func):#func用来接收被修饰函数func<---download_movie
    62. def inner(url):#url接收参数
    63. start_time = time.time()
    64. res = func(url)#func(url)<----download_movie(url)
    65. end_time = time.time()
    66. print(f'电影下载时间:{end_time - start_time}')
    67. return res#把res即(download_movie(url))---->inner
    68. return inner#(download_movie(url))---->time_record
    69. download_movie = time_record(download_movie)
    70. download_movie('https://www.jd.com/')
    71. >>>开始下载电影
    72. 电影下载成功
    73. 电影下载时间:3.0002450942993164
    74. #3、有多个参数
    75. import time
    76. def download_movie(*args, **kwargs):
    77. print('开始下载电影')
    78. time.sleep(3)#模拟下载时间
    79. print('电影下载成功')
    80. return '小泽.mp4'#把'小泽.mp4'
    81. def time_rcod(func):
    82. def inner(*args, **kwargs):
    83. start_time = time.time()
    84. res = func(*args, **kwargs)
    85. end_time = time.time()
    86. print(f'电影下载时间:{end_time - start_time}')
    87. return res
    88. return inner
    89. download_movie = time_rcod(download_movie)
    90. download_movie('https://www.baidu.com/')
    91. >>>开始下载电影
    92. 电影下载成功
    93. 电影下载时间:3.000089168548584
  • 装饰器模板

    1. def wrapper(func):
    2. def inner(*args,**kwargs):
    3. #添加功能
    4. res = func(*args,**kwargs)
    5. #添加功能
    6. return res
    7. return inner
    8. def func1():
    9. pass
    10. func1 = wrapper(func1)#func1被修饰函数,wrapper修饰函数
    11. func1()
  • 装饰器语法糖

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

    @:装饰器的语法糖

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

    1. # 统计函数执行时间装饰器
    2. def wrapper(func): # 被装饰对象
    3. def inner(*args, **kwargs): # 被装饰对象的参数
    4. # 调用前增加新功能
    5. start_time = time.time()
    6. # 调用被装饰对象,并接收返回值
    7. res = func(*args, **kwargs)
    8. # 调用后添加新功能
    9. end_time = time.time()
    10. print(end_time - start_time)
    11. return res
    12. return inner
    13. # func函数需要执行3秒
    14. # 无参装饰器
    15. # 使用装饰器
    16. @wrapper # wrapper(func) ---> func
    17. def func():
    18. time.sleep(3)

原文链接:http://www.cnblogs.com/yafeng666/p/11843169.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号