首页 › 论坛 › 置顶 › 在Python中过度使用“is”而非“==”的风险
-
作者帖子
-
2025-05-28 11:54 #24015Q QPY课程团队管理员
如果你已经使用Python一段时间了,可能在代码中使用过
is和==。它们看起来相似,读起来也很像。但在底层,它们的功能却截然不同。当你本意是使用==时却使用了is,可能会导致微妙而棘手的错误,这些错误非常难以追踪。is和==之间有什么区别?==检查两个值是否相等。is检查两个变量是否指向内存中的同一个对象。
这里有一个简单的方法来记住它:
👉 == → “这些东西看起来一样吗?”
👉
is→ “这些东西真的是同一个对象吗?”快速示例
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True: 内容相同 print(a is b) # False: 内存中的对象不同尽管
a和b包含相同的列表值,但它们不是同一个对象。Python 创建了两个独立的列表。危险的地方
问题出现在开发者假设
is的行为与==相同,或反之,尤其是因为有时is由于 Python 的内部优化而“意外”工作。示例 1:字符串
x = "hello" y = "hello" print(x == y) # Trueprint(x is y) # True? ...有时是对于
is来说,这可能是True,因为 Python 会“驻留”(重用)短字符串以节省内存。但请看这个:a = "hello world! this is a very long string" b = "hello world! this is a very long string"print(a == b) # True print(a is b) # False突然间,
is不再有效,尽管字符串是相等的。为什么?因为 Python 没有对较长的字符串进行驻留。在这里依赖is会导致不稳定、不一致的结果,这些结果取决于你无法控制的因素,比如字符串长度或 Python 实现。示例 2:整数
Python 还缓存了介于
-5和256之间的小整数。x = 256 y = 256 print(x is y) # True a = 257 b = 257 print(a is b) # False编写一些“通过”某些测试但在生产环境中失败的代码是很容易的。这些错误在后期调试时几乎是不可能的。
那么,什么时候应该使用
is?使用
is是有其合理用途的。但这些用途是特定且罕见的。在检查单例对象时使用
is例如:
if my_var is None: ...这是检查
None的正确方式,因为None是一个单例。在 Python 中只有一个None对象。其他有效的情况:
-
my_obj is True
-
my_obj is False
但即使对于
True和False,在数据密集型代码(例如 pandas、NumPy)中,使用==通常更安全,因为这些库重新定义了什么是“真值”。真实世界的错误场景
以下是我见过的一些真实错误:
错误 1:循环中的错误比较
for item in my_list: if item is "done": # 哎呀这可能对某些字符串有效,但对其他字符串则会静默失败。正确的检查是:
for item in my_list: if item == "done": break错误2:数据验证中的假阴性
user_input = input("请输入 yes 或 no: ") if user_input is "yes": # 即使输入为 'yes' 也可能失败 print("确认!")你可能永远不会知道这个失败,除非你的用户输入
"yes"但没有任何反应。错误 3:不可靠的条件逻辑
x = 1000 y = 10 * 100if x is y: # 错误!即使值相同
do_something()这将静默地不执行
do_something(),即使大多数人会说“1000等于1000。”何时使用哪一个?
- 除非你100%确定是在检查身份,否则请使用
==。 - 仅在检查
None或与哨兵对象比较时使用is。 - 不要依赖Python的内部优化,如字符串驻留或小整数缓存。这些是实现细节,可能在不同版本或平台之间发生变化。
操作 使用 ==?使用 is?值相等 ✅ ❌ 对象身份 ❌ ✅ 与 None比较❌ ✅ 与常量比较(例如,字符串,整数) ✅ ❌ 编写可靠、可移植的代码 ✅ ❌(除了 None) -
作者帖子
- 哎呀,回复话题必需登录。