鱼C论坛

 找回密码
 立即注册
查看: 1252|回复: 5

[已解决]关于闭包的内存问题

[复制链接]
发表于 2020-7-21 23:51:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
各位鱼油晚上好,关于闭包我有一个非常不解的地方。我看了一个教程视频,讲者说闭包会有这样一个特性,就是闭包会保存外函数输入实参时的状态,不会被外函数传入新的实参所覆盖,具体例子如下
def func(a,b):
     c = 10
     def func1():
         s = a+b+c
         print(s)
     return func1


x = func(5,6)
x()
y = func(3,4)
y()
结果分别是21和17。如果分别打印id(x)和id(y)的话,可以看到x和y的内存地址是不一样的

讲者的解释是,因为传入的实参是数字,数字是不可变的,5和6,3和4被分配在了不同的内存上,那么x和y就一定在不同的内存上,因为内存不同,所以不会被相互覆盖

于是我觉得非常好奇,就做了以下操作
def func(a,b):
     c = 10
     def func1():
         s = a+b+c
         print(s)
     return func1


x = func(5,6)
print(id(x))
x()
y = func(5,6)
print(id(y))
y()
结果如下:
id(x) = 2643407263488
x() = 21
id(y) = 2643406349072
y() = 21

可以看到x()和y()的值是一样的,但是地址不同了。传入的参数明显是一样的,所以应该和传参的数据类型没关系。

我想知道的是:

1.这两组5和6是放在同一组内存上吗?如果是的话,那么x和y的地址就和参数的地址无关了,那么他们和谁有关?
2.如果这两组5和6不是放在同一地址上,那么为什么它们的地址不一样?很明显他们都是func()的局部参数。
3.闭包中的数据到底是如何写入内存的?


感谢各位鱼油。

最佳答案
2020-7-22 08:58:36


1.这两组5和6是放在同一组内存上吗?如果是的话,那么x和y的地址就和参数的地址无关了,那么他们和谁有关?


试试这段代码就知道是不是同一内存了:
def func(a, b):
    print(id(a),id(b))

x = func(5, 6)
y = func(5, 6)
输出结果:
140726224828320   140726224828352
140726224828320   140726224828352
可以看到内存地址相同

x 和 y 的地址和你设置的返回值有关系,而你设置的内置函数,就像局部变量一样,每个你返回的  func1 都是互不关联的,所以 id 不同

2.如果这两组5和6不是放在同一地址上,那么为什么它们的地址不一样?很明显他们都是func()的局部参数。


x、y 传入的 5 和 6 id 是相同的,而返回的 func1 是互不关联的,因为这是属于这个函数内部的,类似于局部变量每次的作用空间都只在 func 函数内,而不在全局作用域,导致每次的 id 并不相同

3.闭包中的数据到底是如何写入内存的?


就是按照正常方式写入吧


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-22 08:58:36 | 显示全部楼层    本楼为最佳答案   


1.这两组5和6是放在同一组内存上吗?如果是的话,那么x和y的地址就和参数的地址无关了,那么他们和谁有关?


试试这段代码就知道是不是同一内存了:
def func(a, b):
    print(id(a),id(b))

x = func(5, 6)
y = func(5, 6)
输出结果:
140726224828320   140726224828352
140726224828320   140726224828352
可以看到内存地址相同

x 和 y 的地址和你设置的返回值有关系,而你设置的内置函数,就像局部变量一样,每个你返回的  func1 都是互不关联的,所以 id 不同

2.如果这两组5和6不是放在同一地址上,那么为什么它们的地址不一样?很明显他们都是func()的局部参数。


x、y 传入的 5 和 6 id 是相同的,而返回的 func1 是互不关联的,因为这是属于这个函数内部的,类似于局部变量每次的作用空间都只在 func 函数内,而不在全局作用域,导致每次的 id 并不相同

3.闭包中的数据到底是如何写入内存的?


就是按照正常方式写入吧


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-22 10:50:15 | 显示全部楼层
我和楼上的意见一致,只是做一些补充。
x和y 的值 其实都是 func 函数返回的 func1,它们不相同的原因是 每次运行函数func内的代码时,会重新为func1分配地址。
说的明白一点就是在
x = func(5, 6)
时运行了 func() 函数,此时内部的 func1 被分配了一个地址。
同理
y = func(5, 6)

时也分配了一个地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-22 22:10:55 | 显示全部楼层
nahongyan1997 发表于 2020-7-22 11:29
python 对 1-100 之间的数字 的内存地址已经进行了固定已达到在引用时提升速度的目的,所以不管你的哪些变 ...

这个我已经知道了,但是我觉得这个不是我要问的问题,不过还是谢谢你的回答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-22 22:11:27 | 显示全部楼层
°蓝鲤歌蓝 发表于 2020-7-22 10:50
我和楼上的意见一致,只是做一些补充。
x和y 的值 其实都是 func 函数返回的 func1,它们不相同的原因是  ...

好的,我明白了,谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-22 22:13:00 | 显示全部楼层
Twilight6 发表于 2020-7-22 08:58
试试这段代码就知道是不是同一内存了:

好的,感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-19 20:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表