Python中传入函数的同名参数id()未改变,如何解释此行为?
为什么Python函数内外同名变量的id一致,deepcopy后也不变?
你遇到的问题核心是Python对小整数的缓存机制,加上不可变对象的特性共同导致的,下面一步步拆解:
1. 先搞懂变量名和对象的本质
Python里的变量名只是「指向对象的引用」,不是对象本身。当你把外部的var传入函数时,函数内部的var是一个新的引用,但初始时它和外部var指向同一个对象,所以此时两者的id()必然相同——id()返回的是对象的内存地址,不是变量名的地址。
第一段代码里的var = var完全是无效操作,只是把同一个对象重新赋值给自身引用,自然不会改变id。
2. deepcopy为什么没改变id?
Python为了优化性能,会对**-5到256之间的整数对象进行全局缓存**,这些整数对象在程序运行期间只会创建一次,所有用到它们的地方都会复用同一个对象。
你测试用的3正好在这个缓存范围内,哪怕用deepcopy,它也不会创建新的整数对象,而是直接返回缓存里的那个,所以id依然不变。
验证:用超出缓存范围的整数测试
如果把变量改成257(超出小整数缓存范围),再运行第二段代码,就能看到id变化了:
from copy import deepcopy def func(var): print(id(var), "1st inside function") var = deepcopy(var) print(id(var), "2nd inside function") return var var = 257 print(id(var), "1st outside function") var = func(var) print(id(var), "2nd outside function")
运行结果会显示:函数内deepcopy后的id和初始的不同,外部接收返回值后的id也和原来的不同,这才是你原本预期的行为。
总结
- 同名变量是不同的引用,但初始会指向同一个对象,所以id相同
- 小整数(-5到256)被Python全局缓存,复用同一个对象,哪怕deepcopy也不会创建新对象
- 对于不可变对象(整数、字符串、元组等),修改变量本质是让引用指向新对象,但如果对象在缓存范围内,新对象可能就是原来的那个
内容的提问来源于stack exchange,提问作者user6669602
相关产品推荐
相关产品推荐

