理解 Python 如何将参数传递给函数,对于防止数据意外更改和正确设计代码极为重要。
在传统编程语言中,如 C 或 Java,使用按值传递 (copy by value) 或按引用传递 (copy by reference)。但 Python 使用的是不同的模型——按对象引用调用 (有时称为 "按共享调用")。
许多开发人员错误地认为 Python 总是按引用或按值传递参数。这必然会导致可变对象在调用代码中意外被修改。
在 Python 中,函数参数的值是对传递给函数的对象的引用。这意味着:
示例:
# list - 可变的 (mutable) def add_item(lst): lst.append(42) my_list = [1, 2, 3] add_item(my_list) print(my_list) # [1, 2, 3, 42] # int - 不可变的 (immutable) def add_num(x): x = x + 1 num = 10 add_num(num) print(num) # 10
关键特征:
在 Python 中,参数总是按引用传递吗?
不,在 Python 中,传递的是对对象的引用,而对象的行为取决于它是否是可变的。不可变对象在任何修改下都会创建新对象。
可以在函数中重新赋值可变参数,以影响外部对象吗?
不可以。如果您在函数内部给参数重新赋值,外部对象不会改变——您只是更改了局部引用。
示例:
def reassign_list(lst): lst = [99, 100] my_list = [1, 2, 3] reassign_list(my_list) print(my_list) # [1, 2, 3]
为什么默认接受 list 的函数在多次调用时可能表现奇怪?
因为默认值在函数定义时只创建一次,如果更改它(例如,添加元素),它在后续调用中会发生变化。
def add_element(x, cache=[]): cache.append(x) return cache print(add_element(1)) # [1] print(add_element(2)) # [1, 2]
程序员将列表传递给函数,并期望他们的原始列表不会改变,但函数添加了一个元素。
优点:
缺点:
程序员在函数内部明确复制列表,如果需要返回某些内容,但不想更改原始:
def process_data(data): data = data.copy() # 或 list(data) # 安全处理副本 data.append('报告') return data
优点:
缺点: