在下面的函数中,L 存储每次调用期间的值。
例如,如果我调用f(1), L 现在是[1]。当我再次调用它时,前一个 L 会附加新值。所以现在 L 是[1,1]。
def f(a, L=[]):
L.append(a)
return L
但是在这个函数中:
i = 5
def f(arg=i):
print arg
i = 6
无论我调用这个函数多少次,参数仍然5- 它不会在调用之间保持更新。
为什么这没有更新但列表更新的原因是什么?
在下面的函数中,L 存储每次调用期间的值。
例如,如果我调用f(1), L 现在是[1]。当我再次调用它时,前一个 L 会附加新值。所以现在 L 是[1,1]。
def f(a, L=[]):
L.append(a)
return L
但是在这个函数中:
i = 5
def f(arg=i):
print arg
i = 6
无论我调用这个函数多少次,参数仍然5- 它不会在调用之间保持更新。
为什么这没有更新但列表更新的原因是什么?
这是一个很好的问题。发生这种情况的原因是因为函数的默认参数作为单个对象存储在内存中,而不是每次调用函数时都重新创建。
因此,当您将列表[]作为默认参数时,在该程序期间将永远只有一个列表。因此,当您添加到列表时,您将添加到列表的那个副本中。对于像5. 但是,数字在 Python 中是不可变的,因此当您更改以数字开头的默认参数时,您实际上是在使其指向一个新数字而不是编辑该5对象,而列表上的许多操作会在原地改变列表而不是而不是返回一个新列表。
http://docs.python.org/3/tutorial/controlflow.html#default-argument-values
重要警告:默认值仅评估一次。当默认值是可变对象(例如列表、字典或大多数类的实例)时,这会有所不同。
推荐的解决方案是,如果您需要空列表默认参数的行为,而每次调用函数时都没有相同的空列表默认参数,请执行以下操作:
def f(a, L = None):
if L is None:
L = []
L.append(a)
return L
现在,对函数的单独调用会评估空列表的创建 - 而不是一次。
a.append()不同于i = 6. 第一个更改数组,但数组保持相同的对象(相同但不相等)。另一方面,后者为变量分配了一个全新的值。它不会改变任何对象(int 无论如何都不是可变的)。