为何() is ()返回True而(1,) is (1,)返回False?
Python中
is运算符与元组实例的困惑解析 这个问题确实挺容易让人摸不着头脑的——明明元组是不可变类型,为啥空元组() is ()返回True,带元素的(1,) is (1,)却返回False?我当初刚接触Python身份检查的时候也纠结过这个点,咱们一步步拆解清楚:
先明确核心区别:is vs ==
首先得把基础概念掰明白:
==:检查两个对象的值是否相等,本质是调用对象的__eq__()方法做值比对is:检查两个对象的身份是否相同,也就是判断它们是否指向内存中的同一个地址(等价于直接比较id()返回的内存标识)
逐个解析你的例子
1. None is None → True
Python在启动时就会创建唯一的None实例,属于全局单例设计。所有用到None的地方,本质上都是引用这个唯一的内存地址,所以身份检查必然返回True。
2. [] is [] → False
列表是可变类型,Python不会对可变类型的字面量做实例缓存。每次你写[],解释器都会在堆内存中新建一个列表实例,两个字面量列表自然是不同的对象,身份检查返回False。
3. () is () → True
空元组是个特殊的优化案例!Python解释器会全局缓存空元组的实例——因为空元组完全没有状态,复用它不会有任何问题,所以不管你写多少次(),都是指向同一个内存地址,身份检查返回True。
4. (1,) is (1,) → False
这就是最容易困惑的点了:非空元组虽然是不可变类型,但Python不会对所有非空元组做全局缓存。原因很简单——非空元组的组合无限多,缓存所有可能的非空元组会占用大量内存,完全不现实。
每次你直接写(1,)这种字面量时,解释器都会创建一个全新的元组实例,哪怕内容和另一个字面量元组完全一样,它们的内存地址也是不同的,所以is检查返回False。
不过如果是复用同一个元组引用,结果就不一样了:
t1 = (1,) t2 = t1 print(t1 is t2) # 输出True,因为t2是t1的引用,指向同一个对象
补充:Python的对象缓存规则
Python只会对部分高频使用的不可变小对象做全局缓存优化,比如:
- 小整数(默认范围是-5到256)
- 空元组
() - 单个字符的字符串,或者一些短字符串(具体规则由解释器版本决定)
而对于包含其他元素的非空元组、长字符串等,解释器不会自动缓存,每次字面量创建都会生成新实例。
内容的提问来源于stack exchange,提问作者paperino9
相关产品推荐
相关产品推荐

