【问题标题】:Are strings cached?是否缓存了字符串?
【发布时间】:2017-03-09 01:21:34
【问题描述】:
>>> a = "zzzzqqqqasdfasdf1234"
>>> b = "zzzzqqqqasdfasdf1234"
>>> id(a)
4402117560
>>> id(b)
4402117560

但是

>>> c = "!@#$"
>>> d = "!@#$"
>>> id(c) == id(d)
False
>>> id(a) == id(b)
True

为什么只有在分配字符串时才能得到相同的 id() 结果?

已编辑:我将“ascii string”替换为“string”。感谢反馈

【问题讨论】:

  • 这些都是ascii字符串...
  • 还要注意,这里的实习(缓存)是一个 CPython 实现细节,它取决于 很多 的东西。请注意,如果你把它放在一个脚本中,你会得到与在 REPL 中运行它不同的结果......

标签: python string


【解决方案1】:

这与 ASCII 与非 ASCII 无关(您的“非 ASCII”仍然是 ASCII,它只是标点符号,而不是字母数字)。 CPython,作为实现细节,interns string constants that contain only "name characters"。在这种情况下,“名称字符”与正则表达式转义 \w 的含义相同:字母数字加下划线。

注意:这可以随时更改,并且永远不应依赖,这只是他们碰巧使用的优化。

据推测,这个选择是为了优化使用getattrsetattrdicts 以​​少量字符串文字等为键的代码,其中实习意味着所涉及的字典查找通常以结束进行指针比较并完全避免比较字符串(当两个字符串都被保留时,它们在定义上要么是同一个对象,要么不相等,因此您可以完全避免读取它们的数据)。

【讨论】:

  • 非常感谢。您能详细解释一下“实习方式”吗?
  • @ner0:短版:内部字符串是全局查找表中的字符串,可确保每个值的唯一标识。因此,虽然两个非驻留字符串可能具有相同的值,但却是完全不同的对象,但如果两个字符串都被驻留,则不会发生这种情况,这意味着可以通过简单的指针比较来比较两个驻留字符串的相等性,而不是比较长度,然后一个一个地检查字符。 Python 实习生每个类、属性、变量(尽管它通常不用于本地范围)、函数等的名称,因为指针检查速度查找。
  • 它还会自动实习(或做一些非常等价的事情)空字符串和全长 1 ASCII(可能是 latin-1?)字符串,所以无论你如何制作它们,它们都是单例的明确地实习他们。同样,所有这些都是实现细节;如果他们认为它可以提高性能、内存使用、代码简单性等,它可以随时更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
相关资源
最近更新 更多