以下是三个python代码:
======= No.1 =======
def foo(x, items=[]):
items.append(x)
return items
foo(1) #return [1]
foo(2) #return [1,2]
foo(3) #return [1,2,3]====== No.2 ========
def foo(x, items=None):
if items is None:
items = []
items.append(x)
return items
foo(1) #return [1]
foo(2) #return [2]
foo(3) #return [3]====== 3号=======
def foo(x, items=[]):
items.append(x)
return items
foo(1) # returns [1]
foo(2,[]) # returns [2]
foo(3) # returns [1,3]对于1号代码,由于没有提供items的值,我认为它应该始终采用默认值[]。但参数items的行为类似于静态变量,保留其值以供后续使用。2的代码按照我的预期执行:每次调用foo时,items都会采用缺省值None。至于代码3,我完全不知道。为什么上面三段代码的执行方式如此不同?你能解释一下吗?谢谢。
PS:我使用的是python 3.3.1
发布于 2013-08-22 09:20:51
"Least Astonishment" and the Mutable Default Argument
这篇stackoverflow文章回答了你的问题,因为Python函数是带有状态的对象,名为"item“的参数在多次调用之间保留了状态。
它有它的用途:
def calculate(a, b, c, memo={}):
try:
value = memo[a, b, c] # return already calculated value
except KeyError:
value = heavy_calculation(a, b, c)
memo[a, b, c] = value # update the memo dictionary
return value正如这里所解释的,http://effbot.org/zone/default-values.htm
发布于 2013-08-22 09:16:07
源代码[]不是值。它是一个计算结果为列表的表达式。如果你评估它一次,你会得到一个列表;如果你多次评估它,你会得到多个列表。要认识到的关键一点是,默认参数只对默认表达式求值一次并存储它;因此,如果默认参数是一个列表,则每次调用时它始终是相同的列表。
发布于 2013-08-22 09:16:37
项的默认列表对象的定义似乎发生在函数定义时。如果您传入某些内容,items变量将使用您传入的对象,否则将默认使用该默认列表对象。
因为示例1和示例3没有重新定义默认列表对象(而示例2每次都将列表设置为空),所以对它所做的更改是累积的。在示例3中,传入一个单独的空list对象以在items变量中使用意味着您第二次执行该函数不会对您定义的默认list对象产生任何影响。
https://stackoverflow.com/questions/18370109
复制相似问题