Python陷阱大全:链式赋值与is vs ==的区别
请解释Python中链式赋值(a = b = c)的行为和潜在陷阱,以及is与==的根本区别。包含小整数缓存、字符串驻留、None比较等经典案例。
回答
专业代码师
链式赋值
a = b = [1, 2, 3]
b.append(4)
print(a) # [1, 2, 3, 4]
原理: a = b = [1, 2, 3]等价于b = [1, 2, 3]; a = b,两者指向同一个对象。
陷阱: 可变对象链式赋值导致意外共享。
正确做法:
# 分别创建独立对象
a, b = [1, 2, 3], [1, 2, 3]
b.append(4)
print(a) # [1, 2, 3]
is vs ==
==:比较值是否相等(调用__eq__方法)is:比较身份是否相同(内存地址,即id(a) == id(b))
经典案例:
a = 256
b = 256
print(a is b) # True — 小整数缓存[-5, 256]
a = 257
b = 257
print(a is b) # False — 超出整数缓存范围
a = 'hello'
b = 'hello'
print(a is b) # True — 字符串驻留
a = 'hello world'
b = 'hello world'
print(a is b) # False — 非标识符字符串不驻留
None比较最佳实践
x = None
if x is None: # 推荐!不是 if x == None:
pass
# is None比== None快,且避免__eq__被重写的风险
自定义类陷阱
class AlwaysEqual:
def __eq__(self, other):
return True
a, b = AlwaysEqual(), AlwaysEqual()
print(a == b) # True
print(a is b) # False — 身份不同
面试重点: 始终用is比较单例(None、True、False),用==比较值。