数智应用帮
柔彩主题三 · 更轻盈的阅读体验

函数参数传递方式:搞懂值传递和引用传递的实际应用

发布时间:2026-01-10 21:01:25 阅读:41 次

函数参数传递方式:值传递还是引用传递?

写代码时,调用函数传参是家常便饭。但你有没有遇到过这样的情况:在函数里改了参数的值,外面的变量却没变?或者相反,一改全跟着变了?这背后其实就是函数参数传递方式在起作用。

值传递:传的是“副本”

值传递就像复印文件。你把一份文档交给同事处理,他拿去复印了一份,在复印件上涂涂改改,原件还在你手里,一点没动。编程中,基本数据类型比如整数、浮点数、布尔值,大多采用值传递。

看个例子:

def modify_value(x):
    x = x + 10
    print("函数内 x =", x)

num = 5
modify_value(num)
print("函数外 num =", num)

输出结果是:

函数内 x = 15
函数外 num = 5

函数里的 xnum 的一个副本,改 x 不会影响原始的 num

引用传递:传的是“地址”

引用传递更像是共享网盘里的文件链接。你把一个文档的链接发给同事,他打开后直接编辑,你再打开看,内容已经变了。这是因为你们操作的是同一个文件。在 Python、Java 等语言中,列表、字典、对象这类复杂类型,传递的是引用。

举个实际场景:你在写一个统计用户订单的小程序,要把订单列表传给一个处理函数。

def add_discount(orders):
    for i in range(len(orders)):
        orders[i] = orders[i] * 0.9  # 打九折

order_list = [100, 200, 150]
add_discount(order_list)
print(order_list)

输出是:[90.0, 180.0, 135.0]。你会发现原列表被修改了。因为传进去的是列表的引用,函数内操作的就是原始数据。

Python 的特殊之处:对象引用传递

Python 官方说法是“按对象引用传递”。听起来有点绕,其实可以理解为:参数传递时,传的是对象的引用,但这个引用本身是值传递。也就是说,你不能改变引用指向的对象地址,但可以修改对象的内容。

比如:

def reassign_list(lst):
    lst = [4, 5, 6]  # 重新赋值,指向新对象

def append_to_list(lst):
    lst.append(4)  # 修改原对象内容

my_list = [1, 2, 3]
reassign_list(my_list)
print(my_list)  # 输出 [1, 2, 3],没变

append_to_list(my_list)
print(my_list)  # 输出 [1, 2, 3, 4],变了

第一个函数里,lst = [4,5,6] 让局部变量指向了一个新列表,不影响外面的 my_list。而第二个函数通过 append 修改了原列表的内容,所以外部能感知到。

实际开发中的注意事项

在团队协作或维护老代码时,如果不清楚参数会不会被修改,很容易埋坑。比如你传了个配置字典进去,结果函数偷偷加了字段,后续逻辑可能就乱了。

解决办法很简单:如果不想让原数据被改,传参前先复制一份。

config = {'timeout': 30, 'retries': 3}
process_config(config.copy())  # 传副本,保护原数据

或者用 list(my_list)dict.copy()copy.deepcopy() 根据需要选择深浅拷贝。

理解参数传递方式,不只是为了应付面试,更是写出稳定、可维护代码的基础。下次传参前,不妨多想半秒:我传的到底是值,还是引用?