关于Python中CPython字符串interning机制的问题
小弟今天对 interning 还有 Python 中 str 类型的实现比较感兴趣
现在有一个问题,就是我看到了 PyUnicodeObject 这个相关的文件有一个函数 PyUnicode_InternInPlace,我看了下这个函数主要应该是做 interning 的,但是是否我们平常赋值 str 类型时就会调用这个函数呢?
还有一个点我也不太确定,就是 str 类型是不是在现阶段 (python3.3 之后) 底层实现就是 PyUnicdoeObject 了呢,这个我也暂时没有找到依据。看到了一个 pep 文件
PyUnicodeObject 主要内容在 Include/unicodeobject.h 和 Objects/unicodeobject.c 两个文件
然后 PyUnicode_InternInPlace 定义在这里。
关于Python中CPython字符串interning机制的问题
http://guilload.com/python-string-interning/ 应该只有 compile-time 的字符串才会 intern
https://docs.python.org/3.0/whatsnew/3.0.html py3 默认 Unicode string 作为 str
CPython的字符串驻留(interning)机制是一种内存优化技术,它会自动缓存某些字符串对象,使具有相同值的不同变量引用同一个内存对象。这主要发生在编译时和运行时对标识符(如变量名、函数名)以及长度≤1的字符串进行缓存。
关键点:
- 编译时驻留:源代码中的标识符(如
"hello"作为变量名)和字符串字面量会被自动驻留。 - 运行时驻留:通过
sys.intern()函数可以手动驻留字符串,适用于大量重复的字符串场景(如文本处理)。 - 自动驻留规则:长度≤1的字符串、仅包含ASCII字母/数字/下划线的字符串通常会被自动驻留,但具体实现可能因CPython版本而异。
示例代码:
import sys
# 自动驻留示例
a = "hello"
b = "hello"
print(a is b) # 输出 True,因为"hello"被自动驻留
# 手动驻留示例
x = sys.intern("a_long_string_that_might_not_be_interned")
y = sys.intern("a_long_string_that_might_not_be_interned")
print(x is y) # 输出 True
# 非驻留情况示例
c = "hello world!"
d = "hello world!"
print(c is d) # 可能输出 False,长字符串可能不被自动驻留
注意:字符串驻留是CPython的实现细节,不应依赖is进行字符串相等性比较,始终使用==。
总结:理解驻留机制有助于优化内存使用,但不要依赖其行为进行逻辑判断。
感谢,第二个链接我详细看看
如果过是交互器解释器的话,写在一行应该也会 interning,我之前看了这篇文章: https://www.codementor.io/satwikkansal/do-you-really-think-you-know-strings-in-python-fnxh8mtha
比如:
a,b=“wtf!”,"wtf!"
a is b # True
REPL 和普通 Py 程序应该都是要过同样的 compile 阶段的吧

