python 中函数传参是值传递还是引用传递

这个问题网上众说纷纭,有的答案不完全正确,有的答案没有解释清楚。

这里先说我认为正确的答案:

如果学习过 cpp 的话,说传值或者传引用都不准确,直接理解为传地址(指针)就好了,不管可变对象还是不可变对象都是传地址。

详细解释,在函数内:

  • 对传入参数的赋值操作,是创建新的对象,可以理解为声明新的变量,自然不会影响到函数外变量
  • 对传入参数所指对象的修改操作,如 list 的 append,由于是指针,因此修改了函数外变量,注意在 python 中不可变对象类型是不包含可以修改对象的接口的,即便有些接口看起来像修改了,也是返回了新的对象,而不是对原对象的修改,即不是原地修改
  • 这也解释了当传递复杂类型参数:a = tuple(b = list(), 1, 2, 3) 这种数据时,虽然 a 是不可变类型,但通过 a[0].append() 依然可以成功修改 b,也意味着修改了 a,且函数外变量会也会被修改的原因

综上所述,也可以理解为传引用,但要注意,这里的“引用”二字是广义的,不要狭义得理解为是 cpp 中的引用,两者是不同的,在 cpp 中对函数内传入的引用参数执行赋值操作,将会影响到函数外的变量。