Python中pyobject与id的疑问:对象引用及输出差异解析
问题解答
先看你提供的代码:
f='a'.lower b='a'.lower() c='a'.lower() d='a' #RED print(id(f)) print(id(b)) # line 6 print(id(c)) # line 7 print(id('a'.lower)) #YELLOW print(id('a')) print(id(d)) #GREEN print(id(f())) # line 11 print(id('a'.lower())) # line 12
你的观察是对的:黄色和绿色部分输出相同id,红色部分每条语句结果不同。下面逐个解答你的疑问:
1. b和c是否未引用字符'a'?
b和c确实引用的是字符'a',你可以通过print(b == 'a')验证,结果会是True。它们的id和'a'/d不同,是因为Python的字符串驻留机制:
'a'和d这类编译期就能确定的字符串字面量,会被Python自动驻留到全局字符串池里,所以它们的id相同;- 而
'a'.lower()是运行时通过方法调用动态生成的字符串,哪怕结果是'a',Python不会强制将这类动态生成的字符串驻留,所以b和c的id和字面量'a'不一样,但值完全相同。
2. 为什么第6、7行与第11/12行输出id有差异?
核心原因是对象的引用状态和内存回收机制:
- 第6、7行的b和c是被变量绑定的对象,只要变量还存在,这些对象就不会被Python回收,会一直占用内存地址,所以它们的id是固定且唯一的;
- 第11、12行的
f()和'a'.lower()生成的是临时对象——这些对象没有被任何变量绑定,执行完id()调用后就没有引用了,Python会立即回收它们的内存。当下一次生成新的临时字符串对象时,会复用之前被回收的内存地址,所以这两行的id看起来相同。
简单说:有变量引用的对象不会被回收,id固定;临时对象用完就被回收,新对象复用内存地址,所以id重复。
内容的提问来源于stack exchange,提问作者howdy
相关产品推荐
相关产品推荐

