问题: Python中==和is

👇 点击展开/折叠 面试背诵模板(建议先背这个) == 比较两个对象的值是否相等(内容相同),调用对象的 __eq__ 方法;is 比较两个对象的内存地址是否相同(是否为同一个对象),即 id() 是否相等。None、True、False 和单例对象(如空元组)应使用 is 比较,数值和字符串建议使用 ==(但小整数和短字符串因驻留机制可能 is 也返回 True,但不可依赖)。is 比 == 更快,因为仅比较地址。
---

核心区别速览

维度 == is
比较内容 值(内容)是否相等 内存地址(id)是否相同
调用方法 调用 __eq__ 直接比较指针
适用场景 判断内容是否一致(如字符串、列表) 判断是否为同一个对象(如单例、None)
性能 较慢(可能涉及递归比较) 极快(仅地址比较)
可重写 ✅ 可通过 __eq__ 重写 ❌ 不可重写

典型示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b) # True(值相同)
print(a is b) # False(不同对象,内存地址不同)
print(a is c) # True(同一对象)

# 小整数驻留(CPython)
x = 256
y = 256
print(x is y) # True(缓存复用,但不应依赖)
x = 257
y = 257
print(x is y) # False(超出缓存范围,不同对象)

使用场景速查表

场景 使用方式 理由
判断 None x is None None 是单例,且 == 可能被重写导致误判
判断 True / False x is True 或 if x: 布尔值也是单例,且可读性强
判断空容器(列表、字符串) if not lst 或 lst == [] 用 == 更直观,判断值空而非同一对象
判断两个大字符串内容相等 str1 == str2 内容是否相同,不关心地址
比较自定义对象 默认 == 比较内存地址,重写 __eq__ 后按值比较 根据业务需求重写

常见陷阱与注意事项

  • 字符串驻留:Python 可能对小字符串(<256字符或仅包含字母数字)进行驻留,导致 is 意外为 True,但这是实现细节,不应依赖。
  • == 的可重写性:若 __eq__ 实现不当(如总是返回 True),会导致 == 行为异常,而 is 不受影响。
  • 浮点数精度:0.1 + 0.2 == 0.3 为 False(精度问题),而 is 必然 False,因此需用 math.isclose() 比较。
  • 容器比较:列表、字典的 == 会递归比较内部元素,而 is 仅比较容器对象本身。