字符串驻留的本质是对象复用,即通过全局驻留池确保相同内容的字符串共享同一内存实例,从而实现引用相等(a is b 为 true)。

字符串驻留的本质是对象复用
Python 的字符串驻留(interning)不是语法特性,而是一种运行时内存优化策略。它通过维护一个全局的“驻留池”(本质是一个字典结构),确保内容完全相同的字符串在内存中只存在一个实例。当新字符串被创建时,解释器会先查这个池:如果已有相同值的驻留对象,就直接返回其引用;否则才分配新内存,并把该对象加入池中。这样多个变量(如 a 和 b)可以指向同一个地址,a is b 就为 True。
哪些字符串会被自动驻留
Python 解释器对部分字符串做自动驻留,但不保证全覆盖,常见情况包括:
- 符合 Python 标识符规则的字符串:仅含字母、数字、下划线,且不以数字开头,例如 "name"、"_id"、"VERSION2"
- 编译期确定的短字符串字面量:如 "hello"、"a"、"",通常长度 ≤ 20 且只含 ASCII 字符更易被驻留
- 代码中直接写出的常量(非拼接、非运行时生成):如 a = "OK"; b = "OK",多数情况下 a is b 成立
- 函数名、类名、模块名等符号名称:它们在解析阶段就被驻留,属于底层机制的一部分
为什么有些字符串不自动驻留
自动驻留有明确边界,主要出于安全与性能权衡:
- 含空格或特殊字符的字符串(如 "hello world"、"user@domain")一般不会自动驻留
- 运行时拼接生成的字符串(如 "he" + "llo" 或 f"{'hello'}")通常绕过自动驻留流程
- 从外部读入的数据(如文件、网络、用户输入)默认不驻留,避免不可控字符串污染驻留池
- 交互式环境(如 IPython、某些 IDE 控制台)可能禁用部分自动驻留,导致行为与脚本执行不一致
手动驻留:sys.intern() 的作用
当你需要确保重复字符串共享对象时,sys.intern() 是唯一可靠手段:
立即学习“Python免费学习笔记(深入)”;
- 调用后,字符串被强制加入驻留池;再次调用同内容字符串,返回池中已有对象
- 适用于日志解析、CSV 表头处理、大量枚举字段(如状态码、分类标签)等场景
- 注意:驻留后的字符串不可修改(本来就不可以),且驻留池中的对象生命周期与解释器一致,不会被 gc 回收
- 示例:import sys; a = sys.intern("status:active"); b = sys.intern("status:active"); print(a is b) → True










