Python3 中 is 和 == 有什么区别?
核心区别
== | is | |
|---|---|---|
| 比较内容 | 值是否相等 | **身份(内存地址)**是否相同 |
| 底层调用 | __eq__() 方法 | 比较 id() 是否相等 |
| 可重载 | ✅ | ❌ |
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True ← 值相等
print(a is b) # False ← 不是同一个对象
print(id(a)) # 140234...
print(id(b)) # 140235...(不同地址)
is 判断的是同一个对象
a = [1, 2, 3]
b = a # b 和 a 指向同一个对象
print(a == b) # True
print(a is b) # True ← 同一个对象
b.append(4)
print(a) # [1, 2, 3, 4] ← a 也变了
小整数缓存与字符串驻留
CPython 对小整数(通常 -5 ~ 256)和短字符串做了缓存优化,可能导致 is 返回意外的 True:
# 小整数缓存
a = 100
b = 100
print(a is b) # True ← CPython 复用同一对象
a = 1000
b = 1000
print(a is b) # False ← 超出缓存范围,不同对象
# 字符串驻留
s1 = "hello"
s2 = "hello"
print(s1 is s2) # True ← 短字符串被驻留复用
s1 = "hello world!"
s2 = "hello world!"
print(s1 is s2) # 不确定,依赖解释器实现
注意:不要依赖这种缓存行为来判断值是否相等,应始终用 ==。
is 的正确用法:与单例对象比较
is 最适合与 None、True、False 这类单例对象比较:
# ✅ 推荐
if value is None:
...
if result is not None:
...
if flag is True:
...
# ❌ 不推荐(虽然通常能工作,但语义不准确)
if value == None:
...
None 在 Python 中是全局唯一的单例,用 is 比较既语义正确,又比 == 少一次方法调用。
__eq__ 可被重载
== 实际调用左侧对象的 __eq__ 方法,可以自定义:
class AlwaysEqual:
def __eq__(self, other):
return True # 与任何对象都"相等"
obj = AlwaysEqual()
print(obj == 42) # True
print(obj == "abc") # True
print(obj is 42) # False ← is 不受 __eq__ 影响
总结
==:比较值,调用__eq__,日常比较用这个is:比较身份(内存地址),仅在判断是否为同一对象时使用- 最佳实践:只在与
None、True、False比较时用is,其余场景用== - 不要依赖 CPython 的小整数缓存和字符串驻留来使用
is比较值