当前位置:   article > 正文

python闭包的详细解读_python闭包的理解

python闭包的理解

1、闭包的定义

  1. 闭包是嵌套在函数中的函数。

  2. 闭包必须是内层函数对外层函数的变量(非全局变量)的引用。

2、理解闭包

  • 被引用的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系。

  • 自由变量不会再内存中消失。

  • 外部函数返回了内部函数

通俗点说:

                闭包是一个函数,这个函数是嵌套在另外一个函数里边,且这个函数引用了外层函数的变量(非全局变量)

3、 闭包书写步骤

  • 定义外部函数

  • 定义外部函数,在内部函数中使用外部函数的变量

  • 外部函数返回内部函数的地址(内部函数名就饿内部函数的地址)

  1. # 定义内部函数:
  2. def outer(num):
  3. # 2.定义内部函数,在内部函数中使用外部函数的变量
  4. def inner(num1):
  5. print(num + num1)
  6. # 3.外部函数返回内部函数的地址
  7. return inner # 函数名字就是函数地址
  8. if __name__ == '__main__':
  9. # 创建闭包实例
  10. func = outer(100) # 此时func相当于是inner
  11. # 调用闭包
  12. func(10) # 此时调用inner函数,保存的num值为100
  13. # 可以创建多个闭包实例,不同的闭包实例之间,不会相互影响

 4、闭包的使用

需求:

        根据配置信息使用闭包实现不同人的对话信息,例如对话:       

                张三:到北京了吗?

                李四:已经到了,放心吧。

 实现步骤说明:   

  • 定义外部函数接受不同的配置信息参数,参数是人名

  • 定义内部函数接受对话信息参数

  • 在内部函数里面把配置信息和对话信息进行拼接输出

  1. def outer(name):
  2. # 定义内部函数,参数是 说话的信息
  3. print(f'{name}:到北京了吗?')
  4. def inner(name1):
  5. # 内部函数中,将name和info进行拼接输出
  6. print(f'{name1}:已经到了,放心吧。')
  7. # 外部函数返回内部函数的地址
  8. return inner
  9. # 创建闭包实例
  10. if __name__ == '__main__':
  11. func = outer('张三')
  12. func('李四')

 注意点:由于闭包引用了外部函数的变量,则外部函数的变量没有及时释放,消耗内存。

5、闭包修改外部函数变量(理解) 

函数内部想要修改全局变量,使用global关键字
在闭包函数内部,想要修改外部函数的局部变量,需要使用nonlocal关键字

  1. def outer():
  2. num = 10
  3. def inner():
  4. # num = 100 # 不是修改外部变量的值,重新定义的局部变量
  5. nonlocal num # 声明使用外部变量 num 不重新定义
  6. num = 100
  7. print(f'调用inner之前:{num}')
  8. inner()
  9. print(f'调用inner之后:{num}')
  10. return inner
  11. func = outer()
  12. func()

 6、闭包的作用

保存局部信息不被销毁,保证数据的安全性

 7、如何判断一个嵌套函数是不是闭包

  • 1,闭包只能存在嵌套函数中

  • 2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。

案例1 :

  1. def wrapper():
  2. a = 1
  3. def inner():
  4. print(a)
  5. return inner
  6. ret = wrapper()
  7. #例一是闭包

案例2:

  1. # 例二:
  2. a = 2
  3. def wrapper():
  4. def inner():
  5. print(a)
  6. return inner
  7. ret = wrapper()
  8. #例二不是闭包

案例3:

  1. # 例三:
  2. def wrapper(a,b):
  3. def inner():
  4. print(a)
  5. print(b)
  6. return inner
  7. a = 2
  8. b = 3
  9. ret = wrapper(a,b)
  10. #也是闭包

8、如何用代码判断闭包?

查看这个函数有没有自由变量就行了

  1. # 函数名.__code__.co_freevars 查看函数的自由变量
  2. print(avg.__code__.co_freevars) # ('series',)
  3. # 函数名.__code__.co_varnames 查看函数的局部变量
  4. print(avg.__code__.co_varnames) # ('new_value', 'total')
  5. # 函数名.__closure__ 获取具体的自由变量对象,也就是cell对象。
  6. # (<cell at 0x0000020070CB7618: int object at 0x000000005CA08090>,)
  7. # cell_contents 自由变量具体的值
  8. print(avg.__closure__[0].cell_contents) # []

 上面案例三最难判断是不是闭包,为了进一步确认,用代码判断闭包

  1. # 例三:
  2. def wrapper(a,b):
  3. def inner():
  4. print(a)
  5. print(b)
  6. return inner
  7. a = 2
  8. b = 3
  9. ret = wrapper(a,b)
  10. #如何用代码判断闭包?
  11. print(ret.__code__.co_freevars)
  12. ('a', 'b')
  13. Process finished with exit code 0

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

闽ICP备14008679号