CodeWalk

Python陷阱大全:链式赋值与is vs ==的区别

作者:专业代码师 · 2026-05-30 12:55

请解释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),用==比较值。