编程Python后端开发工程师

在Python中,什么是对象的可变性(mutable/immutable)?这如何影响函数的工作和参数的传递?请举例说明典型错误。

用 Hintsage AI 助手通过面试

答案。

可变性指的是是否可以在不改变其标识符(内存地址)的情况下修改对象:

  • 可变对象(例如,list,dict,set)可以被修改:添加元素、修改或删除。
  • 不可变对象(例如,int,str,tuple,frozenset)在创建后不能被修改——任何"修改"都会创建一个新对象。

对函数的影响:

  • 当将可变对象传递给函数时——函数可以对其进行修改。
  • 对于不可变对象,即使在函数内部"替换"它们,也不会发生变化。

示例:

def f(lst): lst.append(42) data = [] f(data) print(data) # [42] def f2(x): x += 1 n = 1 f2(n) print(n) # 1

诱导性问题。

"以下代码将输出什么?"

def foo(bar=[]): bar.append(1) return bar print(foo()) print(foo())

答案: 将输出:

[1]
[1, 1]

因为函数参数在定义时只被初始化一次,而不是每次调用时。列表(和其他可变对象)作为函数参数——是一个常见的陷阱。

由于对主题细微差别缺乏了解而导致的真实错误示例。


故事

在REST API中,通过带有默认参数的函数返回列表:

def get_default_items(items=[]): items.append('x') return items

经过几次调用发现,列表不断增长,而只希望获得一个元素。


故事

在函数中计划"替换"字符串:

def replace_word(word): word.replace('a', 'b') word = 'data' replace_word(word) print(word) # 希望得到'dbtb', 实际得到'data'

str方法不修改原始字符串,而是返回一个新字符串,但忽略了返回值。


故事

在处理嵌套结构时:

original = [[1, 2], [3, 4]] copy = original[:] copy[0][0] = -1 print(original) # [[-1, 2], [3, 4]]

使用了浅拷贝,以为只改变了副本,但嵌套对象仍然是共享的。