最近,我参加了一个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'
值。
修改
我检查了所有的链接,发现它有一个pygg“gotcha”为begginers,但是要感谢答案,不能选择这两个,所以我要去第一个。
答案 0 :(得分:1)
list1
有'a'
,因为使用extendlist('a')
创建的列表会附加到与extendList(10)
相同的列表
毫无疑问,这是Python处理默认参数及其状态模型的详细结果。您甚至可以认为这是一个错误,因为它违反了闭包属性(如果Python的方法应该是闭包)。
例如Ruby中的等效代码:
def extendList(val, list=[])
list << val
return list
end
返回
extendList(10)
# => [10]
extendList(123, [])
# => [123]
extendList('a')
# => ['a']
Ruby就是这种情况,因为Ruby方法是闭包,也就是说,每个方法调用都围绕着它自己的本地环境。
答案 1 :(得分:1)
实际上,这不是那么基本,这有点像蟒蛇陷阱: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