is判断对象是否为同一内存地址,用于None/单例等恒等性比较;==比较值相等,依赖__eq__方法,适用于常规数据比对。

is 判断的是不是同一个对象
Python 中 is 不是比较值,而是检查两个变量是否指向**同一块内存地址**。这在判断单例、None、小整数或短字符串时特别关键——因为它们可能被缓存复用。
常见错误现象:if x == None: 被误用,PEP 8 明确要求写成 if x is None:;又比如 [1,2] is [1,2] 返回 False,哪怕内容一模一样。
-
is是恒等性(identity)比较,底层调用id() - 仅当两个变量引用完全相同的对象时才为
True - 对可变对象(如列表、字典)几乎从不适用,除非你明确在复用同一个实例
== 比较的是值相等,但行为取决于 __eq__
== 是相等性(equality)比较,默认会调用对象的 __eq__ 方法。内置类型已实现合理逻辑,但自定义类若没重写 __eq__,就退化为 is 行为——这点常被忽略。
使用场景:验证用户输入、结构化数据比对、测试断言中检查输出内容是否符合预期。
立即学习“Python免费学习笔记(深入)”;
- 字符串、数字、元组等不可变类型,
==和is在某些情况下结果相同,但纯属巧合(比如小整数-5到256缓存) - 列表、集合、自定义类实例默认不重写
__eq__时,a == b实际等价于a is b - 性能上,
==可能触发遍历或计算(如比较两个大列表),而is总是 O(1)
小整数和字符串的缓存陷阱
CPython 对小整数(-5 到 256)和部分字符串做了驻留(interning),导致看似“不同创建”的对象意外共享地址,让 is 返回 True。但这不是语言规范保证的行为,换解释器或版本可能失效。
示例:257 is 257 在交互式环境里可能是 False,但在 .py 文件中因编译优化又可能是 True——别依赖它。
- 永远不要用
is比较数字或字符串的“值”,除非你真在调试内存布局 -
sys.intern()可手动驻留字符串,但仅限确定需高频比对且内容可控的场景 - 跨进程/序列化后,对象身份必然丢失,
is失效
None、True、False 必须用 is 判断
这是唯一被广泛接受且安全的 is 使用场景。因为 None 是单例对象,全局唯一;True 和 False 同理。用 == 虽然通常也能过,但语义不清,还可能被恶意重载的 __eq__ 干扰。
错误写法:if x == None: 或 if x == True:;正确写法只有 if x is None: 和 if x is True:(不过后者极少需要,直接 if x: 更常见)。
-
None是关键字,不能被重新赋值,所以is绝对可靠 - 工具如
pylint、flake8会警告== None类写法 - 注意:
if not x:和if x is None:完全不同,前者对空列表、0、空字符串也成立
== 后下意识把 None 也套进去,或者看到两个字符串相等就以为 is 也行——那不是错在语法,是错在没想清楚自己到底要问“是不是同一个东西”,还是“看起来一不一样”。










