有人可以向我解释这个非常基本的 Python 代码吗?

Can someone explain this really basic Python code to me?

最近,我去参加了一个 Python 开发人员职位的工作面试。以下代码是问题之一。我只需要写输出。

def extendList(val,list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s " %list1
print "list2 = %s " %list2
print "list2 = %s " %list3

输出为:

list1 = [10, 'a'] 
list2 = [123] 
list2 = [10, 'a']

我想了解为什么第一个列表 list1 具有 'a' 值。

编辑

我检查了所有链接,发现它是一个 python "gotcha" 适合初学者的链接,但要感谢答案,不能同时选择两个,所以我选择第一个。

list1'a' 因为使用 extendlist('a') 创建的列表附加到与 extendList(10)

相同的列表

这无疑是 Python 处理默认参数及其状态模型的方式细节的结果。你甚至可以说这是一个错误,因为它违反了闭包 属性(如果 Python 的方法应该是闭包)。

例如Ruby中的等效代码:

def extendList(val, list=[])
  list << val
  return list
end

returns

extendList(10)
# => [10]

extendList(123, [])
# => [123]

extendList('a') 
# => ['a']

Ruby 就是这种情况,因为 Ruby 方法是闭包,也就是说,每个方法调用都带有它自己的局部环境。

实际上,这不是那么基本,它有点 python 陷阱:Mutable Default Parameter

与每次函数调用后打印比较:

>>> def extendList(val,list=[]):
...     list.append(val)
...     return list
...
>>> list1 = extendList(10)
>>> print "list1 = %s " %list1
list1 = [10]
>>> list2 = extendList(123,[])
>>> print "list2 = %s " %list2
list2 = [123]
>>> list3 = extendList('a')
>>> print "list2 = %s " %list3
list2 = [10, 'a']

另外:

>>> list1 is list2
False
>>> list1 is list3
True