当前位置:   article > 正文

一文带你了解Python中的闭包和装饰器

一文带你了解Python中的闭包和装饰器

闭包

当调用完函数后,函数内定义的变量就销毁了,但有时需要保存函数内的这个变量,并在这个变量的基础上完成一系列的操作 ,那怎么办呢?               答案就是使用闭包!

作用:

        闭包可以保存函数内的变量,而不会随着调用完函数而被销毁。

语法:

  1. # 外部函数
  2. def 外部函数名(外部参数):
  3. # 内部函数
  4. def 内部函数名(内部参数):
  5. ...[使用外部函数的变量]
  6. return 内部函数名

构成条件:

        ①有嵌套:在函数嵌套(函数里面再定义函数)的前提下;

        ②有引用:内部函数使用了外部函数的变量(还包括外部函数的参数);

        ③有返回:外部函数返回了内部函数名。

应用场景----累加器:

  1. """
  2. 累加器
  3. nonlocal:
  4. 外部函数的变量必须用nonlocal修饰,这样改变量才可以被内置函数修改
  5. """
  6. # 1.定义外部函数
  7. def func_outer(): # 有嵌套
  8. # 2.定义外部函数变量
  9. a = 100
  10. # 3.定义内部函数
  11. def func_inner(): # 有嵌套
  12. # 核心细节:外部函数的变量必须用nonlocal修饰,这样改变量才可以被内置函数修改
  13. nonlocal a
  14. # 累加器动作 然后输出
  15. a = a+1 # 有引用,引用外部函数变量
  16. print(f'a的值为{a}')
  17. # 4.返回内置函数
  18. return func_inner # 有返回,返回内部函数名
  19. # 调用func_outer函数
  20. my_fn = func_outer() # 等价于: my_fn = func_inner
  21. my_fn() # 101
  22. my_fn() # 102
  23. my_fn() # 103

装饰器

作用:

        装饰器的作用是不改变原有函数的基础上,给原有函数增加额外功能。 装饰器本质上就是一个闭包函数

构成条件:

        ①有嵌套:在函数嵌套(函数里面再定义函数)的前提下;

        ②有引用:内部函数使用了外部函数的变量(还包括外部函数的参数);

        ③有返回:外部函数返回了内部函数名;

        ④有额外功能:给需要装饰的原有函数增加额外功能。

四种场景写法:

  1. """
  2. 装饰器细节:
  3. 1. 装饰器的目的是: 在不改变原有函数的基上, 给原函数增加 额外功能
  4. 2. 装饰器常用与法主要是: 语法糖形式, 即: @装饰器名
  5. 3, 使用装饰器的小技巧: 保证装饰器的 内置函数格式 和 原函数(要被装饰的函数) 格式保持一致,都是无参无返回,无参有返回...
  6. """
  7. # 场景一:无参无返回
  8. # 1.定义装饰器
  9. def print_info(fn_name): # fn_name: 表示要被装饰的函数名
  10. def fn_inner(): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
  11. print('正在努力计算中...')
  12. fn_name()
  13. return fn_inner
  14. # 2.定义原函数,(即: 要被装饰的函数)
  15. @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
  16. def get_sum():
  17. a = 10
  18. b = 20
  19. sum = a + b
  20. print(f'求和结果为{sum}')
  21. # 3.调用函数
  22. # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
  23. get_sum()
  24. # 场景二:无参有返回
  25. # 1.定义装饰器
  26. def print_info(fn_name): # fn_name: 表示要被装饰的函数名
  27. def fn_inner(): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
  28. print('正在努力计算中...')
  29. return fn_name()
  30. return fn_inner
  31. # 2.定义原函数,(即: 要被装饰的函数)
  32. @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
  33. def get_sum():
  34. a = 10
  35. b = 20
  36. sum = a + b
  37. print(f'求和结果为{sum}')
  38. return sum
  39. # 3.调用函数
  40. # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
  41. get_sum()
  42. # 场景三:有参无返回
  43. # 1.定义装饰器
  44. def print_info(fn_name): # fn_name: 表示要被装饰的函数名
  45. def fn_inner(a,b): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
  46. print('正在努力计算中...')
  47. fn_name(a,b)
  48. return fn_inner
  49. # 2.定义原函数,(即: 要被装饰的函数)
  50. @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
  51. def get_sum(a,b):
  52. sum = a + b
  53. print(f'求和结果为{sum}')
  54. # 3.调用函数
  55. # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
  56. get_sum(100,200)
  57. # 场景四:有参有返回
  58. # 1.定义装饰器
  59. def print_info(fn_name): # fn_name: 表示要被装饰的函数名
  60. def fn_inner(): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
  61. print('正在努力计算中...')
  62. return fn_name()
  63. return fn_inner
  64. # 2.定义原函数,(即: 要被装饰的函数)
  65. @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
  66. def get_sum():
  67. a = 10
  68. b = 20
  69. sum = a + b
  70. print(f'求和结果为{sum}')
  71. return sum
  72. # 3.调用函数
  73. # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
  74. get_sum()
  75. # 场景四:有参有返回
  76. # 1.定义装饰器
  77. def print_info(fn_name): # fn_name: 表示要被装饰的函数名
  78. def fn_inner(a,b): # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致
  79. print('正在努力计算中...')
  80. return fn_name(a,b)
  81. return fn_inner
  82. # 2.定义原函数,(即: 要被装饰的函数)
  83. @print_info # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
  84. def get_sum(a,b):
  85. sum = a + b
  86. print(f'求和结果为{sum}')
  87. return sum
  88. # 3.调用函数
  89. # get_sum = print_info(get_sum) # 原始写法, 看懂即可, 一般不用.
  90. get_sum(33,66)

带参数的装饰器:

  1. """
  2. 案例:
  3. 演示不带参数的装饰器.
  4. 目的:
  5. 演示1个装饰器 可以用来 装饰 多个函数
  6. 需求:
  7. 定义一个既能装饰减法运算, 又能装饰加法运算的装饰器, 即: 带有参数的装饰器
  8. """
  9. # 1.定义装饰器
  10. def logging(flag): # 有嵌套,接收:装饰器的参数 + -
  11. def decorator(fn_name): # 有嵌套 接收原函数名
  12. def inner(num1,num2): # 有嵌套 给函数增加额外功能
  13. if flag =='+':
  14. print('正在努力计算 加法 中...')
  15. if flag =='-':
  16. print('正在努力计算 减法 中...')
  17. return fn_name(num1,num2)
  18. return inner
  19. return decorator
  20. # 2.定义函数,加法运算
  21. @logging('+')
  22. def get_sum(a,b):
  23. sum = a+b
  24. return sum
  25. # 3.定义函数,减法运算
  26. @logging('-')
  27. def get_sub(a,b):
  28. sub = a-b
  29. return sub
  30. # 4.调用函数
  31. sum = get_sum(10,7)
  32. print(f'相加为{sum}')
  33. sub = get_sub(10,7)
  34. print(f'相减为{sub}')

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/963749
推荐阅读
相关标签
  

闽ICP备14008679号