python - 字典未引用的字符串?

标签 python string dictionary reference cpython

看看这段 Python 代码:

from gc import get_referrers as refs
x = 'x'
d = {x:x}
print(d in refs(x))

它打印错误。这本身就很奇怪,但当您考虑以下内容时会变得更奇怪:

  • 如果 x 是数字(整数、 float 、复数、分数、小数)而不是字符串,它仍然打印 False。对于 bytes 和 bytearray 也是如此。但对于所有其他类型(如果用作键,则可散列,如元组或卡住集 - 但许多其他类型,如果仅用作值),它会打印 True。

  • 如果 d 是包含 x 的任何其他容器(集合、列表、元组...),它会打印 True。仅对于字典,它会打印 False。此外,x 是键还是值,或者如上所述,两者都是无关紧要的。

我认为在 Python 中每个对象都是一个引用(与具有基本类型的 Java 或 Ruby 不同,后者的值类型为小整数),但现在看来 str 和 int 有点像原始类型,它们不是引用。但另一方面,为什么只在字典中??

我也知道从 -5 到 256 的整数被缓存在 CPython 中(小字符串可以被保留),所以不对它们进行重新计数是有意义的,因为它们永远不会被删除,但这适用于任何整数(和长字符串)我试过,比那个范围大得多。

有人知道这里发生了什么吗?

---更新---

越来越好奇……似乎 datetime.{datetime, date, time} 类具有相同的“未引用”行为。现在,我知道 一个 AnyStr 和 Number 的共同点:它们的散列是随机的,每个 session 都有一个盐。但这没有任何意义,因为即使这些只是字典中的,而不是键,也会观察到行为。并且值没有散列。或者他们是?

最佳答案

来自gcmodule.c:

Certain types of container cannot participate in a reference cycle, and so do not need to be tracked by the garbage collector. Untracking these objects reduces the cost of garbage collections. However, determining which objects may be untracked is not free, and the costs must be weighed against the benefits for garbage collection.

...

Dictionaries containing only immutable objects also do not need to be tracked. Dictionaries are untracked when created. If a tracked item is inserted into a dictionary (either as a key or value), the dictionary becomes tracked. During a full garbage collection (all generations), the collector will untrack any dictionaries whose contents are not tracked.

基本上,由于 Python 中的对象是引用计数的,垃圾收集器的目标是打破引用循环,当最后一个引用消失时,其他未引用的对象将被销毁。为了优化,垃圾收集器不会跟踪某些根本无法参与引用循环的对象。

所以,字符串引用了。但是,垃圾收集器对这些字典根本不感兴趣,因此 gc.get_referrers() 不会列出它们。

关于python - 字典未引用的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31131598/

相关文章:

ios - 存储大字符串数组时编译器错误的解决方法

C语言。如何将字符串添加到链接列表中

c - 我的函数填充字符串值

javascript - 下划线 : map through object (even if undefined)

Python如何做列表字典的字典的.values().values()

python - xlsxwriter 中的粗边框

python - 如何指定返回类型与输入类型相同?

python - Django自定义表单验证IP地址和域名

python - Linux IPC : Locking, 但不是基于文件的锁定

c++ - 如何解析文件内容并加载到 map 中