Sunday面试指南

Python 的 is 和 == 有什么区别?为什么判断 None 用 is,比较字符串却不用?

下面是一段教学用的模拟面试。

🧑‍💻 面试官: Python 的 is 和 == 有什么区别?

🙋‍♂️ 我: 都能判断两个值相不相等。

🧑‍💻 面试官: 两张内容相同的列表,is 为什么可能是 False?

🙋‍♂️ 我: 因为不是同一个对象。

🧑‍💻 面试官: 那我试了两个相同的小整数,is 又是 True。你会拿这个结果写比较逻辑吗?

“内容一样”和“同一个对象”不是一回事。缓存恰好让对象复用,不能改变我们想表达的判断。

面试速答(60 秒版)

is 判断两个引用是不是指向同一个对象;== 判断它们按类型定义的相等规则是否相等,可能调用自定义的比较逻辑。

两张分别创建的列表,即使元素完全相同,也可以 == 为 True、is 为 False;两个变量指向同一张列表,is 才为 True。

判断 None 通常使用 is None,因为我们要识别这个特定的单例对象,也避免触发对象自定义的相等行为。

比较字符串、数字等值,使用合适的相等比较。不要依赖小整数缓存或字符串驻留时观察到的 is 结果,那不是表达值相等的可靠方式。

is 看身份,== 看相等规则

图:is 看身份,== 看相等规则。

知识点详解:我们要比较的是对象身份,还是对象内容?

两张一样的清单,也可以是两张纸

分别创建两张列表,内容都为 1、2;再让第三个变量指向第一张列表。

Python

a = [1, 2]
b = [1, 2]
c = a
assert a == b
assert a is not b
assert a is c

a 和 b 的内容相同,但对象不同。c 没有复制列表,只是增加了一个指向 a 的引用。所以改变 a 的内容,c 也会观察到。

TypeScript

const a = [1, 2];
const b = [1, 2];
const c = a;
console.assert(a !== b);
console.assert(a === c);

这段代码只是对照对象身份。JavaScript 的数组严格相等比较按对象身份判断,并不会像 Python 列表的 == 一样自动逐项比较内容。因此没有把两个语言的操作符机械对应。

== 也不是固定的一套“深比较”

Python 的相等关系由类型定义。列表会按其比较规则处理元素,自定义类则可以实现 eq。

因此,不能把 == 概括成“无论什么对象,都递归比较全部字段”。有些类型比较的是业务键,有些比较返回的行为又不同。具体表达式规则见 Python 语言参考。

这也解释了为什么判断 None 更适合 is:我们不是请求某个对象描述它是否“等于空”,而是在判断它是不是 None 本身。

小整数与字符串测试为什么会骗人?

解释器可以复用某些对象,编译方式也可能影响常量如何创建。于是,在某个交互窗口里观察到相同数字的 is 为 True,并不意外。

但业务要判断的是“这两个数的值是否相等”,不是“解释器这次是否复用了同一份对象”。比较字符串也是同样的道理。

不要通过反复换数字找出一个“缓存分界点”,再把这个分界写成语言保证。实现细节不是业务判断条件。

None 判断,找的是特定对象

图:None 判断,找的是特定对象。

哨兵值为什么很适合身份比较?

假设函数要区分“没有传参数”和“明确传了 None”。仅用 None 当默认值,就分不清这两种情况。

可以创建一个专属哨兵对象,用 is 判断输入是不是它。这时,身份比较表达的正是我们的意图:只有那一个专门创建的对象代表“未提供”。

也要注意,哨兵的身份依赖正确的传递方式。如果跨序列化、跨进程传递,它不一定还是原来的对象,协议需要另外设计。

面试官继续追问

两个变量 is 为 True,内容一定一样吗?

它们在同一时刻指向同一个对象。不过对象之后可能改变;身份一致不代表内容不可变,也不代表并发访问安全。

id 相同能永久代表同一个对象吗?

不能把已经销毁对象的 id 当永久业务标识。身份值可能复用;用户 ID、订单 ID 等业务身份需要自己的稳定规则。

面试速记卡

  • is:判断同一个对象。
  • ==:按类型定义判断相等。
  • None:用 is None 表达单例身份判断。
  • 值比较:不依赖整数缓存或字符串驻留。
  • 跨语言:Python 列表 == 与 JS 数组 === 不是同一规则。

公司面试真题

这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。

浏览公司面试真题 →
简历汪永久免费在线制作简历,模板直接套用、导出无水印,永久免费、下载免费,不需要付费解锁任何功能。去写简历