在 Python 调试过程中,== 和 is 混用导致的 bug 屡见不鲜。这两个看似功能相似的操作符,背后却对应着完全不同的底层逻辑。本文将从官方定义、实际案例、底层原理三个维度,彻底讲清楚它们的区别,帮你避开踩坑。
一、核心定义:值相等 vs 对象同一性
先明确两个核心概念,这是理解区别的基础:
| == | Equality(相等性) | 检查两个对象的内容 / 值是否一致 | 调用对象的 eq() 方法 |
| is | Identity(同一性) | 检查两个变量是否指向内存中同一个对象 |
从现象看本质
Case 1:整数(小整数池)
a = 1
b = 1
print(a == b) # 输出:True(值相等)
print(a is b) # 输出:True(指向同一个对象)
原因:Python 为了提升性能,会预先创建并缓存「小整数池」(默认范围:-5 ~ 256)。当你给变量赋值为这个范围内的整数时,不会新建对象,而是直接引用缓存中的对象。因此 a 和 b 指向内存中同一个 1。
注意:如果整数超出这个范围(比如 a=1000; b=1000),a is b 通常会返回 False(不同环境可能有差异),但 a == b 仍为 True。
案例 2:浮点数
c = 1.0
d = 1.0
print(c == d) # 输出:True(值相等)
print(c is d) # 输出:True(多数环境下,简单浮点数也会缓存)
浮点数的缓存机制不如整数稳定,复杂浮点数(如 1.23456)大概率不会被缓存,此时 is 会返回 False,但 == 始终以值为准。
案例 3:字符串(字符串驻留)
# 简单字符串
e = "abc"
f = "abc"
print(e == f) # 输出:True
print(e is f) # 输出:True
# 带空格的字符串
a = "hello world"
b = "hello world"
print(a == b) # 输出:True
print(a is b) # 输出:True(多数环境下触发驻留)
原因:
Python 对不可变、简单的字符串会触发「字符串驻留(Interning)」机制 —— 内容相同的字符串共用同一个内存地址,目的是节省内存。但这个机制不是绝对的:
包含特殊字符 / 复杂拼接的字符串(如 “hello” + " world")可能不被驻留;
动态生成的字符串(如 str(123))通常不被驻留。
案例 4:列表(可变对象)
g = [1, 2, 3]
h = [1, 2, 3]
print(g == h) # 输出:True(值完全相同)
print(id(g)) # 输出:3108129548864(示例地址)
print(id(h)) # 输出:3108132618432(示例地址)
print(g is h) # 输出:False(不同内存地址)
原因:列表是可变对象,每次执行 [1,2,3] 时,Python 都会在内存中新建一个独立的列表对象。哪怕内容完全一样,它们也是两个不同的「容器」,因此 id 不同,is 返回 False。
案例 5:直接赋值(引用传递)
a = [1, 2, 3]
b = a # 将b指向a的内存地址
print(a is b) # 输出:True(同一个对象)
print(a == b) # 输出:True(值自然相等)
# 验证:修改b会影响a
b.append(4)
print(a) # 输出:[1,2,3,4]
结论:b = a 不是复制对象,而是给同一个对象新增一个「别名」(引用)。此时 a 和 b 指向同一块内存,is 必然返回 True。
三、什么时候用 ==?什么时候用 is?
1.判断值是否相等 → 用 ==(90% 的场景)
# 正确用法:判断用户输入是否为"exit"
user_input = input("请输入:")
if user_input == "exit":
print("退出程序")
2.判断对象是否为同一个 → 用 is(特定场景)
# 正确用法:判断是否为None
if data is None:
print("数据为空")
# 错误用法(不报错,但不规范)
if data == None:
pass
四、总结
== 比较值相等,is 比较对象同一性(内存地址);
不可变对象(整数、字符串)可能因 Python 缓存 / 驻留机制,导致内容相同的变量指向同一个对象(is 返回 True),但这是优化行为,不能依赖;
可变对象(列表、字典、集合)只要是新建的(如 []、{}),哪怕内容相同,is 也返回 False;
实际开发中,优先用 == 判断值,仅在判断 None 或验证对象引用时用 is。
掌握 == 和 is 的区别,不仅能避免调试时的坑,更能加深对 Python「一切皆对象」和「引用传递」核心特性的理解。
网硕互联帮助中心




评论前必须登录!
注册