is 比较对象身份(内存地址),等价于 id(a) == id(b),绕过 __eq__ 等方法;== 比较值,调用 __eq__,内置类型已合理实现;None、True、False 必须用 is 判断;小整数和字符串驻留是不可靠的实现细节。

is 比较的是对象身份,不是值
它只看 a 和 b 是否指向内存中同一个对象,等价于 id(a) == id(b)。这个判断完全绕过内容,也不调用任何方法——__eq__、__ne__ 全无效。
常见错误现象:
-
[] is []总是False(每次[]都新建一个列表对象) -
{"x": 1} is {"x": 1}是False,哪怕键值完全一样 -
1000 is 10**3在多数情况下是False,尽管数值相等
== 比较的是值,且可被自定义
== 默认调用对象的 __eq__ 方法。内置类型已实现合理逻辑:列表比元素顺序和内容,字符串比字符序列,数字比数学值。
使用场景与陷阱:
立即学习“Python免费学习笔记(深入)”;
- 自定义类没重写
__eq__时,==会退化为is行为(即比较地址) -
float('nan') == float('nan')是False,但float('nan') is float('nan')也是False(NaN 不等于自身,且每次生成新对象) - 浮点数比较建议用
math.isclose(),而不是直接==
None、True、False 必须用 is 判断
这些是单例对象,Python 保证全局唯一。用 == 虽然多数时候也成立,但语义错位且有风险。
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
正确写法:
-
if x is None:✅ -
if x == None:❌(__eq__可被重载,可能返回非布尔值甚至抛异常) -
if flag is True:或更简洁的if flag:(除非需区分True和真值)
注意:if x is not None: 比 if x != None: 安全得多。
小整数和字符串驻留是 CPython 实现细节,不可依赖
-5 到 256 的整数、短字符串常被缓存复用,所以 256 is 256 是 True,但 257 is 257 在脚本里大概率是 False;"hello" is "hello" 可能为 True,而 "hello world" is "hello world" 在模块级或交互式环境里可能为 False。
关键点:
- 这种行为不跨 Python 实现(PyPy、Jython 不一定相同)
- 不跨版本(未来 CPython 可能调整驻留策略)
- 不跨上下文(函数内、eval 中、不同模块加载顺序都影响结果)
只要你在比较“值是否相等”,就该无条件用 ==;只有当你真正关心“是不是同一个对象”时,才用 is。

















