is比较内存地址,==比较值;is判断是否同一对象,==可被重载;none/true/false必须用is;小整数和字符串驻留是cpython实现细节。

因为 is 比较的是对象在内存中的地址是否相同,而 == 比较的是对象的值是否相等——这是根本差异,不是 bug,也不是偶然。
is 判断的是 id(a) == id(b)
它不看内容,只看是不是同一个对象。比如:
a = [1, 2, 3] b = a a is b # True,因为 b 是 a 的引用,指向同一块内存
但只要对象是独立创建的,哪怕内容一模一样,is 就返回 False:
-
a = [1, 2, 3]和b = [1, 2, 3]→a is b是False -
a = {"x": 1}和b = {"x": 1}→a is b是False -
a = (1, 2)和b = (1, 2)→ 在某些上下文中可能是True(元组不可变 + 常量折叠),但不可依赖
这种行为完全由 id() 决定,无法被类重载,也不受 __eq__ 影响。
== 调用的是对象的 __eq__ 方法
它的逻辑是可定制的,默认行为因类型而异:
- 对
list、dict、set:逐项比较内容 - 对
int、str:值相等即返回True - 对自定义类:若未实现
__eq__,则退化为is;若实现了,就按你写的逻辑走
这意味着 == 可能很慢(比如两个大列表比较),也可能有陷阱:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
-
1 == True是True(因为bool是int子类) -
0 == False同样是True - 但
1 is True是False—— 这是常见误判点
小整数和短字符串的“意外相等”不可靠
CPython 缓存了 -5 到 256 的整数,所以:
100 is 100 # True(缓存内) 257 is 257 # 大概率 False(超出缓存)
字符串也类似:
-
"abc" is "abc"通常为True(字面量 + 驻留) -
"ab c" is "ab c"可能为False(含空格时驻留不保证) -
"he" + "llo" is "hello"在交互式环境里可能True,但在函数中常为False
这些全是 CPython 实现细节,不是语言规范。PyPy、Jython 或未来版本都可能不同。
None、True、False 必须用 is 比较
None 是单例,全局唯一,所以:
- ✅ 正确:
if x is None: - ❌ 危险:
if x == None:—— 若x是自定义类且重写了__eq__,可能返回True即使它不是None
同理,True 和 False 也是单例,但更推荐直接写布尔表达式(如 if x:),而不是显式比较。
最易被忽略的一点:当你在调试时看到 a is b 为 True,不要以为这说明它们“内容一致”——它只说明你意外地让两个变量共享了同一个可变对象,后续修改任一变量都会影响另一个。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










