使用全局 Python 变量引用环境

Referencing Environment with Global Python Variables

提问人:yigitkucuk 提问时间:11/18/2023 更新时间:11/19/2023 访问量:28

问:

在下面的程序中,有一个全局变量 a,我想检查点 1、2、3 和 4 中每个点的引用数。

import sys

a = 'my-string'
print(sys.getrefcount(a))

b = [a]
print(sys.getrefcount(a))

del b
print(sys.getrefcount(a))

c = { 'key': a }
print(sys.getrefcount(a))

当我执行程序时,我看到引用的数量分别为 4、5、4、5。我不明白为什么会这样。

我的第一个想法是,所有全局变量都是从堆栈的静态段分配的,因此,对于每个 、 和 ,都有一个引用,构成 3 个引用。对于每个 ,都有一个参考文献,总共构成 4 个参考文献。ab = [a]c = { 'key': a }print(sys.getrefcount(a))

如果是这样的话,在语句中,第 5 个引用从何而来,尤其是在删除之后?b = [a]c = { 'key': a }b

Python 参考 全局变量

评论

2赞 Barmar 11/18/2023
引用不是对变量的引用,而是对值的引用。
0赞 yigitkucuk 11/18/2023
那么,引用是“my-string”,列表 b 中 a 的值,以及映射到 key 的 a 值?我做对了吗?
1赞 Barmar 11/18/2023
是的。此外,在 的参数列表中还有一个引用。sys.getrefcount()
1赞 Barmar 11/18/2023
我不确定所有引用的位置,它们可能是内部的。
1赞 Barmar 11/18/2023
很容易看出为什么当您将字符串添加到列表或字典时它会上升。

答:

1赞 MegaIng 11/18/2023 #1

我相信refreneces的答案是:

  • 未知的内部,而不是字符串缓存,因为这也发生在其他不可变的文字上,如浮点数或整数(在 -5 到 255 范围之外)。也许是解析的神器?
  • 模块的代码对象的常量表
  • 代码对象(在本例中为字典)的框架局部变量中的条目globals()
  • 将字符串对象传递给getrefcount
  • 而改变的那个是:集合中的引用。

您可以观察到一些关于 CPython 工作方式的有趣事情:

  • 由于相同的文本在整个代码中是完全相同的对象,因此,如果直接引用而不是在整个代码中引用,则数字不会更改"my-string"a
  • 如果您使用浮点数、大/负整数、非空元组和类似的东西等文字,则行为将完全相同。
  • 如果你使用小整数、空元组、布尔文字或类似的魔法对象,你会看到不同的东西,这取决于你的 CPython 版本:要么是一个比其他所有数字高得多的数字,要么你会看到一个非常大的数字,这意味着最高位已被翻转以指示一个 imoortal 对象。
    • 这还包括您可能意想不到的内部字符串,例如 .__init__
  • 如果你使用可变对象,如列表文字 或 ,你会看到一个模式,指示上面列表中的前两个完整不再存在。[]object()set()2,3,2,3