Python采用“对象引用传递”:函数接收对象引用的副本,不可变对象赋值创建新对象,可变对象就地修改影响外部;需用copy()保护原始可变对象。

Python中没有传统意义上的“传值”或“传引用”,而是统一采用“对象引用传递”:函数接收的是实参对象的引用(即内存地址的副本),但这个引用本身是按值传递的。关键在于理解对象的可变性(mutable vs immutable)如何影响外部变量的表现。
不可变对象(如int、str、tuple):看似“传值”
对参数重新赋值(如 x = x + 1)会创建新对象,原变量不受影响,因为不可变对象无法就地修改。
- 函数内修改参数名指向——只改变局部引用,不影响调用方变量
- 字符串拼接、数字运算等操作均生成新对象,原对象和原变量绑定关系不变
可变对象(如list、dict、set):可“就地修改”影响外部
若在函数内调用对象的原地方法(如 lst.append()、dct.update()),因操作的是同一块内存中的对象,外部变量可见变化。
- 使用 += 对列表操作等价于 extend(),属于就地修改
- 但 lst = lst + [1] 是重新赋值,创建新列表,不影响外部
如何安全控制参数行为?
明确意图,避免意外共享:
立即学习“Python免费学习笔记(深入)”;
- 若需保护原始可变对象,传入副本:func(lst.copy()) 或 func(lst[:])
- 若需返回新对象而非修改原对象,函数内显式构造并 return,不依赖副作用
- 文档或参数命名中注明是否修改入参(如 inplace=True)
一个典型误区示例
以下代码常被误认为“传引用所以能改原值”,实则是可变对象特性所致:
def add_item(items):
items.append("new") # ✅ 就地修改,调用方列表变化
def replace_items(items):
items = ["a", "b"] # ❌ 局部重绑定,不影响外部两次调用后,只有第一次改变了原始列表。










