CPython中x[0]、y[0]、z[0]内存地址相同 为何新定义同内容字符串a地址不同
问题原理解析
1. x[0]、y[0]、z[0]地址一致的原因
y = x属于直接引用赋值,y和x指向完全相同的列表对象,列表内元素的内存地址自然完全一致z = x[:]是列表的切片浅拷贝,只会创建新的列表容器对象,容器内所有元素的引用都会直接复制自原列表,因此z[0]和x[0]指向同一个字符串对象。
2. 新定义的a和x[0]地址不同的原因
这个现象是CPython的字符串驻留规则 + 交互式解释器的特性共同导致的:
2.1 自动驻留的触发限制
CPython默认只会对符合标识符命名规则(仅由字母、数字、下划线组成)的字符串执行全局自动驻留,你使用的字符串"test t"包含空格,不符合自动驻留条件,不会被加入全局驻留池,同值字符串不会自动复用对象。
2.2 交互式环境的代码块隔离
你是在Python交互式解释器(Shell)中执行代码,每一行独立输入的内容都是单独的编译单元:
- 定义x的代码行编译时,
"test t"作为当前代码块的常量被创建 - 后续单独输入的
a = "test t"属于全新的独立编译单元,对于没有被全局驻留的字符串,不同编译单元的同值常量不会复用,会新建独立的字符串对象,因此地址不同。
补充验证
你可以通过两种方式验证上述规则:
- 显式调用驻留方法强制同值字符串复用对象:
import sys a = sys.intern("test t") print(id(a) == id(x[0])) # 输出为 True
- 将所有代码写在同一个
.py文件中运行,同一编译单元内的同值常量会被编译优化为同一个对象,此时id(a) == id(x[0])也会返回True,和字符串是否包含空格无关。
内容的提问来源于stack exchange,提问作者Clarence
相关产品推荐
相关产品推荐

