变量赋值时对象复制时机及Python赋值行为的技术疑问
Python变量赋值与对象引用的核心疑问
背景与初始认知
本周学习机器人学期间,通过教授的视频讲座了解到:变量本质是指向存储对象内存地址的引用。教授明确说明,当把一个变量赋值给另一个变量时,两个变量会指向同一个对象(附教授制作的示意图,其中挪威语词汇翻译:navnerom=命名空间,minnet=内存,objekter=对象,eksempelprogram=示例程序)。
此前的GPT4咨询结果
之前曾就「当第二个变量被赋值为另一个已赋值变量的值时,该变量是否指向已存在的对象?」这一问题咨询GPT4,得到的答复是:这取决于数据类型和编程语言:
- 基本数据类型(如数字、布尔值,部分语言的字符串):赋值时会复制值,两个变量存储在不同内存地址,修改一个不会影响另一个;
- 引用数据类型(如对象、数组、列表):赋值后两个变量指向内存中的同一个对象,通过一个变量修改会影响另一个。
GPT4同时给出了Python示例代码:
# 基本数据类型示例 a = 5 b = a b = 10 print(a) # 输出: 5 print(b) # 输出: 10 # 引用数据类型示例 list1 = [1, 2, 3] list2 = list1 list2[0] = 99 print(list1) # 输出: [99, 2, 3] print(list2) # 输出: [99, 2, 3]
实际测试与疑惑
原本认为Python中基本类型赋值时会复制对象到新内存地址,新变量指向该地址,二者可独立修改。但通过Python内置id()函数测试后发现了矛盾:
测试代码:
a = 5 b = a print(id(a)) print(id(b)) a += 1 print(id(a))
输出结果:
140736222585768 140736222585768 140736222585800
从结果可以看到,初始时a和b的id完全相同,说明二者指向同一个对象;修改a后,a的id发生了变化。由此产生三个核心疑问:
- 修改
a时是否创建了新对象? - GPT4的回答是否有误?
- 变量赋值时对象是立即复制还是修改时才复制?
核心解析
1. Python无「基本数据类型」概念
Python的设计逻辑里,所有元素都是对象,包括数字、布尔值这类传统意义上的基本类型。这类对象属于不可变对象——一旦创建就无法修改其内部值。
2. 赋值操作的本质
无论对象类型如何,Python的赋值操作始终是让变量指向对象的引用,不会立即复制对象:
- 执行
b = a时,只是让b指向a当前指向的对象,所以初始时a和b的id相同; - 对于不可变对象,执行
a += 1这类操作时,并非修改原对象,而是创建一个新对象,再让a指向这个新对象。这就是修改后a的id变化、b仍指向原对象的原因,二者后续操作互不影响。
3. GPT4回答的偏差
GPT4的回答混淆了Python与其他语言(如Java、C++)的概念。Python中不存在「赋值时复制基本类型值」的逻辑,所有赋值都是引用传递,区别仅在于对象是否可变:
- 可变对象(如列表、字典):修改对象内部值时,所有指向该对象的变量都会同步看到变化;
- 不可变对象:无法修改内部值,任何看似「修改」的操作都会创建新对象,原对象不受影响,因此不同变量后续操作互不干扰。
4. 复制的时机
Python中对象复制不会在赋值时发生,只有两种场景会创建新对象:
- 显式调用复制方法(如
list.copy()、copy.copy()); - 对不可变对象执行「修改」操作(本质是创建新对象)。
内容的提问来源于stack exchange,提问作者user22419592
相关产品推荐
相关产品推荐

