ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

闭包详解(Python为例)

2021-10-27 18:33:48  阅读:180  来源: 互联网

标签:闭包 __ 函数 为例 Python closure cell lambda


不能简单讲,这就要看一些底层的东西(堆栈结构等等,估计还和编译原理有关),我觉得重点在于延迟绑定怎么知道绑定的外层函数的局部变量


python的闭包是延迟绑定

什么是闭包?
  1. 出现函数嵌套, 即外层函数嵌套内层函数, 这就意味着c没有闭包,因为函数不能嵌套定义, 我猜的, 这块打个flag
  2. 内部函数引用外部函数的局部变量 一般我们知道,在栈中的局部变量在函数后退出后就销毁了, 那有什么办法可以不立即这么做?
  3. 外部函数返回值必须是内嵌函数

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, 这里其实声明普通函数也可以,特意用了一些比较恶心的用法.
从下面代码我们知道什么

  1. 闭包空间就是一个元组,元素为cell对象, 每个cell对象又包含闭包内容和其它的内容
  2. 每个lambda函数引用外部函数的局部变量name和i这才形成了闭包
  3. 我在局部函数中把i值最后改成100,可以看到最后所有闭包空间中的int都是100了, 这个很合理,因为我改的是
    局部变量,你引用了啊(这里我感觉既不是值传递也不是引用传递, 更不是共享传参, 就好像我盯着i这个标签一样,你怎么变,我最终值就怎么变)
  4. 可以看到multipliers()调用之后就会出现延迟绑定, 即我所有匿名函数(这里是否是匿名函数没有关系), 最终闭包空间的所有值都是100

—————
延迟绑定只是一个表面现象,真正要理解我觉得还有一段路要走

看完龙书再回答一波.

标签:闭包,__,函数,为例,Python,closure,cell,lambda
来源: https://blog.csdn.net/qq_32252957/article/details/120998880

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有