函数的缺省参数值(Default Argument Values)
一般情况下,我们可以很自由的给参数赋初值,而不需要考虑任何异常的情况或者陷阱。但是当你给这些参数
赋值为可变对象(mutable object),比如list,dictionary,很多类的实例时,那么你要小心了,因为函数参数
的初值只能被计算一次(在函数定义的时间里)。怎么来理解呢?我们来看下面的例子。
-
def bad_foo(item, my_list=[]):
-
my_list.append(item)
-
return my_list
-
-
print bad_foo('a')
-
-
print bad_foo('b')
-
- print bad_foo('c')
-
['a']
-
['a', 'b']
- ['a', 'b', 'c']
有问题?答案是解释器的输出结果完全正确。由于前面我们说了函数参数的初值只会在函数定义的时间里计
算一次。所以,你在第二次调用函数时,my_list=[]不会再被执行,此时my_list已经不在等于[],而是等于
['a'],以此类推。
为了看清本质,我们将上面的代码改一下,在操作my_list之前,我们先输出my_list。代码如下:
-
>>> def bad_foo(item, my_list=[]):
-
print my_list
-
my_list.append(item)
-
return my_list
-
-
>>> bad_foo('a')
-
[]
-
['a']
-
>>> bad_foo('b')
-
['a']
-
['a', 'b']
-
>>> bad_foo('c')
-
['a', 'b']
- ['a', 'b', 'c']
既然会出现这样的小陷阱,那么我们怎么来避免呢?下面的代码将消除这个小陷阱。
-
>>> def good_foo(item, my_list=None):
-
if my_list is None:
-
my_list=[]
-
my_list.append(item)
-
return my_list
-
-
>>> good_foo('a')
-
['a']
-
>>> good_foo('b')
-
['b']
-
>>> good_foo('c')
-
['c']
- >>>
-
>>> def good_foo(item, my_list=None):
-
print my_list
-
if my_list is None:
-
my_list=[]
-
print my_list
-
my_list.append(item)
-
return my_list
-
-
>>> good_foo('a')
-
None
-
[]
-
['a']
-
>>> good_foo('b')
-
None
-
[]
-
['b']
-
>>> good_foo('c')
-
None
-
[]
-
['c']
-
>>> def good_foo(item, my_list=[]):
-
print my_list
-
if my_list:
-
my_list=[]
-
print my_list
-
my_list.append(item)
-
return my_list
-
-
>>>
-
>>> good_foo('a')
-
[]
-
[]
-
['a']
-
>>> good_foo('b')
-
['a']
-
[]
-
['b']
-
>>> good_foo('c')
-
['a']
-
[]
-
['c']
- >>>
所以,当我们想要给函数参数的初始化为可变对象时,我们要注意到这一点。