You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python的call by object reference概念可视化及核心原理问询

Python的「按赋值传参」与对象-名称关系可视化解析

先掰正核心认知:对象没有「名称」,只有「指向对象的名称」

你听到的「Python对象没有名称」不是敷衍,是本质——Python里的变量(名称)和对象完全是两回事:

  • 对象是内存里实实在在存数据的实体(比如整数5、字符串"hello"、列表[1,2,3]),它本身没有名字,就像你包里的笔记本,本子上不会刻着你的名字。
  • 名称(变量)是你给这个对象贴的「指向标签」,就像你在包的外侧写「我的笔记本」——这个标签和本子是分离的,你可以把标签撕下来贴到另一本本子上,也可以给同一个本子贴多个标签。

用文字可视化这个绑定过程:

  1. 执行x = 5:内存里先生成一个值为5的整数对象(假设内存地址是0x123),然后把名称x和0x123绑定,相当于x→0x123(值5)。
  2. 执行y = x:不是复制5这个对象,而是把名称y也绑定到0x123,变成x→0x123,y→0x123,两个名称指向同一个对象。
  3. 执行x = 10:生成新的整数对象0x456(值10),把x的绑定改成x→0x456,但y还是指向0x123,所以y的值还是5。

不可变对象传参的本质:为什么看起来像「传值」?

Python的函数传参规则叫按赋值传参(Call by Assignment),本质就是执行「形参 = 实参」这个操作——把实参当前的绑定关系复制给形参。

拿不可变对象(数字、字符串、元组)举例:

def change_num(a):
    a = 20  # 这里不是修改原来的10,而是让a绑定新的整数对象20
num = 10
change_num(num)
print(num)  # 输出10

可视化这个传参过程:

  • 调用change_num(num)时,形参a被赋值为num的绑定,也就是a→0x789(值10)。
  • 函数里执行a=20,生成新对象0xabc(值20),把a的绑定改成a→0xabc。
  • 但实参num的绑定还是num→0x789,所以外部的num不受影响,看起来像「传值」,但本质是不可变对象无法被修改,只能重新绑定新对象。

如果是可变对象(列表、字典),就能修改对象本身:

def add_item(lst):
    lst.append(4)  # 直接修改lst指向的那个列表对象
my_list = [1,2,3]
add_item(my_list)
print(my_list)  # 输出[1,2,3,4]

这里形参lst和实参my_list指向同一个列表对象,修改对象的内容会影响所有指向它的名称,因为对象本身变了。

对比你提到的文件类比:差异在哪里?

硬盘上的文件名和文件是强关联的——文件名是文件的标识(快捷方式本质也是指向文件的链接),删除文件名后文件可能还在,但文件名和文件是绑定的。

但Python的名称和对象是弱绑定:

  • 一个对象可以被多个名称指向(比如x = [1,2]; y = x)。
  • 一个名称可以随时切换指向不同的对象(x = 5; x = "hello")。
  • 对象可以没有任何名称(比如执行del x后,如果没有其他名称指向0x123,这个对象会被Python的垃圾回收机制销毁)。

总结核心机制

  1. 对象是数据载体:存在内存中,本身无名称,分为可变(可修改内容)和不可变(内容不可改,只能生成新对象)两类。
  2. 名称是绑定关系:变量名只是指向对象的「指针标签」,和对象完全分离。
  3. 传参是复制绑定:函数传参就是把实参的绑定复制给形参,形参和实参初始指向同一个对象;如果是不可变对象,修改形参只是切换绑定,不影响实参;如果是可变对象,修改对象内容会影响所有指向它的名称。

内容的提问来源于stack exchange,提问作者Swawa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 04:33:36