关于此行为的重要一件事是,Python会缓存一些(大多数情况下)短字符串(通常少于20个字符,但并非针对它们的每种组合),以便可以快速访问它们。这样做的一个重要原因是,字符串在Pyhton的源代码中得到了广泛使用,并且是对某些特殊类型的字符串进行缓存的内部优化。字典是Python源代码中最常用的数据结构之一,通常用于保留变量,属性和名称空间,以及用于某些其他目的,它们都使用字符串作为对象名称。就是说,每次您尝试访问对象属性或访问变量(局部或全局)时,都会在内部启动字典查找。
现在,出现这种奇怪行为的原因是因为Python(cpython实现)在内部处理方面对字符串的处理不同。在Python的源代码中,有一个intern_string_constants 函数,该函数为字符串提供要嵌入 的验证,您可以检查更多详细信息。或查看此综合文章http://guilload.com/python-string- interning/。
还值得注意的是,Pythonintern()
在sys
模块中具有一个函数,您可以使用该函数手动插入字符串。
In [52]: b = sys.intern('a,,')
In [53]: c = sys.intern('a,,')
In [54]: b is c
Out[54]: True
您可以在想要 固定字典查找 时使用,也可以在代码中频繁使用特定的字符串对象时使用此功能。
您不应该将其与 字符串实习 混为一谈的另一点是,当您a == b
创建对同一对象的两个引用时,显然这些关键字具有相同的引用id
。
关于标点符号,如果它们是一个字符,则长度大于一会被屏蔽;如果长度大于一,则不会被缓存。正如评论中提到的那样,原因之一可能是因为关键字和字典键不太可能带有标点符号。
In [28]: a = ','
In [29]: ',' is a
Out[29]: True
In [30]: a = 'abc,'
In [31]: 'abc,' is a
Out[31]: False
In [34]: a = ',,'
In [35]: ',,' is a
Out[35]: False
# Or
In [36]: a = '^'
In [37]: '^' is a
Out[37]: True
In [38]: a = '^%'
In [39]: '^%' is a
Out[39]: False
但是,这些只是您在代码中不能依赖的一些推测。