python字符串驻留自动触发于标识符风格(字母数字下划线)、顶层字面量、空串及单字符;手动用sys.intern()可强制驻留,提升is比较性能,但驻留对象不回收,需慎用于高重复可控场景。

Python 的字符串驻留(intern)机制是一种优化策略,用于减少内存中重复字符串对象的数量。它通过让相同内容的字符串共享同一个对象来节省内存并加速比较操作。但这个机制不是对所有字符串都生效,而是有明确的触发条件和底层逻辑。
什么情况下会自动 intern?
Python 在编译期会对满足特定条件的字符串字面量自动执行 intern 操作:
- 仅包含字母、数字、下划线的标识符风格字符串(如 "hello"、"_123"),通常会被 intern
- 在模块顶层定义的字符串常量(非动态拼接、非运行时生成)大概率被 intern
- 空字符串 "" 和单字符字符串(如 "a")几乎总是被 intern
- 含特殊字符(如空格、连字符、中文、emoji)或以数字开头的字符串(如 "123abc")一般不会被自动 intern
手动调用 intern 的方法与注意事项
可通过 sys.intern() 强制对任意字符串执行驻留:
- 需要先导入 import sys
- 传入字符串后返回其驻留后的对象引用,后续相同内容的字符串可直接复用该对象
- 注意:不能对非字符串类型调用;对已 intern 的字符串再次调用无副作用,仍返回原对象
- 示例:s1 = sys.intern("hello world"); s2 = sys.intern("hello world"); print(s1 is s2) → True
为什么 intern 后的字符串比较更快?
因为 is 比较的是对象身份(内存地址),而普通字符串比较(==)需逐字符比对。当大量字符串需频繁判等(如解析关键字、处理 token)时,先 intern 再用 is 可显著提升性能:
立即学习“Python免费学习笔记(深入)”;
- 适合场景:词法分析器、配置键名匹配、HTTP 方法判断("GET"、"POST")等
- 不适用场景:用户输入、文件读取内容、随机生成字符串等不可预知的内容
- 关键点:只有确保字符串内容可控且重复率高时,intern 才带来收益
intern 的局限性与潜在陷阱
它不是万能的内存优化工具,使用不当反而引入问题:
- 驻留的字符串永远不会被垃圾回收,长期驻留大量非常用字符串会导致内存泄漏
- 多线程环境下,sys.intern() 是线程安全的,但需注意竞态:两个线程同时 intern 相同字符串,结果仍是同一对象
- 交互式环境(如 IPython)中,每次输入的字符串可能不会被自动 intern,行为与脚本执行略有差异
- 不同 Python 版本(尤其是 3.7+ 对 Unicode 处理增强)对 intern 的边界判定略有调整,不宜硬编码依赖










