闭包详解(Python为例)
2021/10/27 20:40:59
本文主要是介绍闭包详解(Python为例),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
不能简单讲,这就要看一些底层的东西(堆栈结构等等,估计还和编译原理有关),我觉得重点在于延迟绑定怎么知道绑定的外层函数的局部变量
python的闭包是延迟绑定
什么是闭包?
- 出现函数嵌套, 即外层函数嵌套内层函数, 这就意味着c没有闭包,因为函数不能嵌套定义, 我猜的, 这块打个flag
- 内部函数引用外部函数的局部变量 一般我们知道,在栈中的局部变量在函数后退出后就销毁了, 那有什么办法可以不立即这么做?
- 外部函数返回值必须是内嵌函数
talk is cheap
#!/usr/bin/python # -*- coding:utf-8 -*- def multipliers(): name = "江湖狗哥我也" i = 0 ret = list() for _ in range(4): lambda_func = lambda x: i * x + (print(name) is None) - 1 # noqa ret.append(lambda_func) print(lambda_func.__closure__) print("the closure variable i: {}".format(hex(id(lambda_func.__closure__[0].cell_contents)))) i += 1 i = 100 return ret if __name__ == '__main__': for item in multipliers(): print("the lambda function output: {}".format(item(2))) print("闭包中的cell对象组成的元组成: {}".format(item.__closure__)) print("取出闭包空间中的整数: {}".format(item.__closure__[0].cell_contents)) for number in list([0, 1, 2, 3, 100]): print(hex(id(number)))
__
result
(<cell at 0x0000029926818FD0: int object at 0x0000029926026910>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) the closure variable i: 0x29926026910 (<cell at 0x0000029926818FD0: int object at 0x0000029926026930>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) the closure variable i: 0x29926026930 (<cell at 0x0000029926818FD0: int object at 0x0000029926026950>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) the closure variable i: 0x29926026950 (<cell at 0x0000029926818FD0: int object at 0x0000029926026970>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) the closure variable i: 0x29926026970 江湖狗哥我也 the lambda function output: 200 闭包中的cell对象组成的元组成: (<cell at 0x0000029926818FD0: int object at 0x00000299260555D0>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) 闭包中的整数值: 100 江湖狗哥我也 the lambda function output: 200 闭包中的cell对象组成的元组成: (<cell at 0x0000029926818FD0: int object at 0x00000299260555D0>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) 闭包中的整数值: 100 江湖狗哥我也 the lambda function output: 200 闭包中的cell对象组成的元组成: (<cell at 0x0000029926818FD0: int object at 0x00000299260555D0>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) 闭包中的整数值: 100 江湖狗哥我也 the lambda function output: 200 闭包中的cell对象组成的元组成: (<cell at 0x0000029926818FD0: int object at 0x00000299260555D0>, <cell at 0x0000029926818FA0: str object at 0x0000029926576DC0>) 闭包中的整数值: 100 0x29926026910 0x29926026930 0x29926026950 0x29926026970 0x299260555d0
我特意加了一个字符串局部变量, name, 这里其实声明普通函数也可以,特意用了一些比较恶心的用法.
从下面代码我们知道什么
- 闭包空间就是一个元组,元素为cell对象, 每个cell对象又包含闭包内容和其它的内容
- 每个lambda函数引用外部函数的局部变量name和i这才形成了闭包
- 我在局部函数中把i值最后改成100,可以看到最后所有闭包空间中的int都是100了, 这个很合理,因为我改的是
局部变量,你引用了啊(这里我感觉既不是值传递也不是引用传递, 更不是共享传参, 就好像我盯着i这个标签一样,你怎么变,我最终值就怎么变) - 可以看到multipliers()调用之后就会出现延迟绑定, 即我所有匿名函数(这里是否是匿名函数没有关系), 最终闭包空间的所有值都是100
—————
延迟绑定只是一个表面现象,真正要理解我觉得还有一段路要走
看完龙书再回答一波.
这篇关于闭包详解(Python为例)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-03用FastAPI掌握Python异步IO:轻松实现高并发网络请求处理
- 2025-01-02封装学习:Python面向对象编程基础教程
- 2024-12-28Python编程基础教程
- 2024-12-27Python编程入门指南
- 2024-12-27Python编程基础
- 2024-12-27Python编程基础教程
- 2024-12-27Python编程基础指南
- 2024-12-24Python编程入门指南
- 2024-12-24Python编程基础入门
- 2024-12-24Python编程基础:变量与数据类型