You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何() 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:19:50