为什么在python中,即使在垃圾收集之后,我仍然能够访问元素?

von4xj4u  于 2022-12-30  发布在  Python
关注(0)|答案(2)|浏览(114)

我想我在这里遗漏了一些东西,但是当我使用gc.collect()执行强制垃圾收集时,我不应该能够访问id(10),因为它没有被任何变量引用,即使我假设id(10)调用正在创建变量,它是否在相同的位置创建?这是wierd

import gc
import time

x = 10
y = x
print('10 id is: ', id(10))
print('x id is: ',id(x))
print('y id is: ',id(y))

x = x+1
y = 11
print('x id is: ',id(x))
print('y id is: ',id(y))
# above is justified
gc.collect(generation=2)
time.sleep(2)
print(id(10))
# but how come is above statement giving the value of id(10) as earlier?

当我运行这个代码片段时:

line1: 10 id is:  140709303001776
line2: x id is:  140709303001776
line3: y id is:  140709303001776
line4: x id is:  140709303001808
line5: y id is:  140709303001808
line6: 140709303001776

那么为什么在第6行,我能够得到和我之前分配的一样的id(10),因为现在x和y指向不同的内存,并且我在打印第6行之前已经收集了垃圾
请帮助我在这个片段是如何内存分配工作,因为这让我感到困惑。

pgpifvop

pgpifvop1#

也许python解释器本身或导入的模块也有一个值为10的变量,所以这里有更多对值10的引用,我扩展了您的代码片段来证明:

import gc
import time
import sys

x = 10
y = x
print('10 id is: ', id(10))
print('x id is: ',id(x))
print('y id is: ',id(y))
print("References to 10:", sys.getrefcount(10))

x = x+1
y = 11
print('x id is: ',id(x))
print('y id is: ',id(y))

gc.collect(generation=2)
time.sleep(2)
print("References to 10:", sys.getrefcount(10))
print(id(10))

我的计算机上的输出:

10 id is:  140076230383168
x id is:  140076230383168
y id is:  140076230383168
References to 10: 20
x id is:  140076230383200
y id is:  140076230383200
References to 10: 18
140076230383168
slhcrj9b

slhcrj9b2#

为了提高效率,Python在缓存中有小整数(从-5256,包括-5),所以当需要的时候,它们永远不会被再次分配,你可以在这个问题和它的答案中读到:What's with the integer cache maintained by the interpreter?
检查值是否缓存的一个好方法是执行a is (a - 1 + 1),只有缓存了a的值,它才会是True

  • 我指的是www.example.com上的CPythonpython.org,其他实现可能会做不同的事情,特别是与gc相关的东西,它不会影响通常的Python代码语义。

相关问题