在 Python3 中,比较两个对象时,is 和 == 分别基于什么依据进行判断?请说明它们的核心区别以及典型应用场景。
考察说明
考察对 Python 对象身份比较与值比较的理解。
回答思路
- 【回答框架 1】== 比较的是两个对象的值是否相等,即调用对象的 __eq__ 方法,默认实现是比较内存地址,但可以被重写。is 比较的是两个对象的身份标识是否相同,即是否指向同一内存地址,等价于 id(a) == id(b)。
- 【回答框架 2】对于不可变对象如小整数、短字符串,Python 可能进行缓存或驻留,导致不同变量引用同一对象,但这是实现细节,不应依赖。例如 a = 1; b = 1; a is b 为 True 依赖于小整数缓存。
- 【回答框架 3】在应用上,通常使用 == 判断值相等,如比较数字、字符串内容;使用 is 判断是否为同一个对象,如与 None 比较时使用 if x is None,因为 None 是单例。
- 【回答框架 4】自定义类中,如果重写了 __eq__ 而不重写 __hash__,可能影响对象在集合中的行为,但 is 不受影响,始终比较身份。
- 【回答框架 5】在可变对象如列表、字典中,即使内容相同,is 也通常为 False,因为它们是不同对象。
- 【关键点 1】== 比较值,is 比较身份。
- 【关键点 2】is 等价于 id 比较。
- 【关键点 3】None 比较应使用 is。
- 【关键点 4】小整数和短字符串可能因缓存导致 is 为 True。
- 【关键点 5】重写 __eq__ 不影响 is 行为。
- 【易错点 1】不要依赖小整数或字符串的驻留机制,不同版本和实现可能有差异。
- 【易错点 2】仅重写 __eq__ 而不重写 __hash__ 可能破坏哈希集合的不变式。