b = a 时,Python 不会复制对象,而是让 b 也指向 a 所指向的那个对象。此时,该对象的“引用计数”加 1list, dict, set),多个引用指向同一个对象时,修改其中一个变量,会影响所有指向该对象的变量int, str, tuple),多个引用指向同一个对象也是完全合法的。# 不可变类型示例 str_a = "hello" str_b = str_a # str_b 和 str_a 指向同一个字符串对象 print(str_a is str_b) # True (确实是同一个对象) # 试图"修改" str_b (实际上是重新赋值) str_b = str_b + " world" # 观察 str_a print(str_a) # 输出: "hello" <-- str_a 没变 print(str_b) # 输出: "hello world" <-- str_b 指向了新创建的对象 # 验证它们现在指向不同的对象 print(str_a is str_b) # False
在 Python 交互式命令行(REPL)中输入: python >>> a = 1000 >>> b = 1000 >>> a is b False 在交互式模式(REPL)中,你输入的每一行虽然被视为独立的“代码块”编译,但它们都运行在同一个全局作用域(Global Scope)中。 第一行 a = 1000:在全局命名空间中创建了一个变量 a,指向一个值为 1000 的整数对象。 第二行 b = 1000:在全局命名空间中创建了一个变量 b。 第三行 a is b:Python 去全局命名空间找 a 和 b,它们都还在。 结论:变量不会因为一行代码执行结束就消失,除非你显式删除它(del a)或者程序退出。 为什么 a is b 是 False?(整数缓存机制) 这才是问题的关键。Python 为了优化性能,会对小整数进行缓存(Interning),但对大整数通常不会。 小整数缓存范围:通常是 [-5, 256]。在这个范围内的整数,无论在哪里创建,Python 都会复用同一个对象。 整数行为:对于超出这个范围的整数(如 1000),Python 默认每次遇到字面量 1000 时,都会创建一个新的整数对象(除非在同一个代码块内被优化器识别)。
a = 1000:
1000。Obj_1 (值 1000)。a 指向 Obj_1。b = 1000:
1000。Obj_2 (值 1000)。b 指向 Obj_2。a is b:
a (指向 Obj_1) 和 b (指向 Obj_2) 是否是同一个对象。Obj_1 不是 Obj_2。False。3. 对比:如果在脚本文件中运行
.py 文件里运行:a = 1000 b = 1000 print(a is b)True。1000,于是让它们指向同一个对象以节省内存。事实 1:变量 a 存储在全局命名空间中,只要不被覆盖或删除,它一直存在。
事实 2:1000 的对象没有被“丢弃”,a 依然紧紧引用着第一个 1000 对象。
事实 3:b 引用的是第二个新创建的 1000 对象。
真相:a is b 为 False 是因为 Python 没有缓存大整数,且 REPL 的逐行执行机制导致创建了两次对象,而不是因为对象被垃圾回收了。