is操作符用于判断两个变量是否指向同一内存地址,即对象身份是否相同;它比较id()值,不触发方法调用,适用于None检查和可变对象共享检测,但不可用于值相等判断。

用 is 操作符判断对象身份,不是值相等
Python 中检测两个变量是否指向同一内存地址,唯一可靠的方式是用 is 操作符。它比较的是对象的标识(identity),即 id() 返回的整数值是否相同。这和 == 完全不同:== 比较的是值,而 is 比较的是“是不是同一个东西”。
常见误用是拿 is 去判断字符串或小整数是否“相等”,比如 "hello" is "hello" 有时返回 True,但这只是 CPython 的字符串驻留(interning)和小整数缓存优化导致的副作用,不能依赖。
-
is的语义明确:只用于判断是否为同一对象(如单例、None、动态创建后未被修改的可变对象) - 对不可变对象(如
str,int,tuple)慎用is判断内容,除非你明确在检查驻留行为 - 对可变对象(如
list,dict, 自定义类实例),is才真正反映“是否共享底层数据”
用 id() 函数手动比对内存地址
id() 返回对象的唯一标识,在 CPython 中就是内存地址(一个整数)。你可以显式调用它做判断,效果和 is 等价,但更啰嗦,也更易出错。
示例:
立即学习“Python免费学习笔记(深入)”;
Python 环境工具专业版功能概述Python 环境工具专业版是一项面向实际任务的技能。它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。核心要点使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。执行完成后建议检查结果是否符合预期,并保留必要记录。使用与执行同时注意输入完整性、执行条件和输出可用性。从功能定位来看,该技能
a = [1, 2, 3] b = a c = [1, 2, 3] print(id(a) == id(b)) # True print(id(a) == id(c)) # False print(a is b) # True print(a is c) # False
- 不要用
id()做跨进程/跨解释器比较——它只在当前 Python 进程内有效 - 某些对象(如某些内置类型临时计算结果)生命周期极短,
id()可能被复用,不建议缓存其返回值长期使用 - 调试时打印
id(x)比看is更直观,但生产代码中优先用is
为什么 is 在检查 None 时是标准写法
PEP 8 明确规定:永远用 if x is None:,而不是 if x == None:。原因很实在:
-
None是单例,全局唯一,is快且安全 - 如果
x是自定义类实例且重载了__eq__,== None可能抛异常或返回意外结果 -
is不触发任何方法调用,零开销;==会调用__eq__,哪怕右边是None
同理,检查是否为 True/False 不该用 is(应该用 if x: 或 if not x:),因为布尔值虽是单例,但语义上它们代表真值性,不是身份判断场景。
可变对象引用共享的真实影响
当你用 is 发现两个变量指向同一可变对象时,意味着修改其中一个会影响另一个。这是实际开发中最常踩坑的地方。
典型场景:
- 函数参数传入列表,函数内部
.append()后原列表被改 —— 因为传的是引用,list_a is list_b成立 - 类属性误设为可变类型(如
default=[]),多个实例共享同一列表,instance1.items is instance2.items为True - 用
copy.copy()浅拷贝后,嵌套的子对象仍共享地址,shallow1.nested is shallow2.nested可能为True
这时候 is 不是“为了判断而判断”,而是帮你定位副作用源头的关键手段。别等到数据莫名被改才去翻内存地址。

















