这个问题在这里已有答案:
作为一名C ++程序员,我在Python中遇到了意想不到的行为。在下面的示例中,输出为:
y:A1
A1
B1
然而,我会期望这个输出:
B1
我使用python 2.7。对我来说,令人惊讶的是,在函数的第二次调用中,默认参数已经具有前一次调用结果的值。它应该不是一个空列表吗?
这是python代码:
def f( x, y=[]):
for z in y:
print "y:" + str(z)
result = y
result.append(x+'1')
return result
l = f('A')
l = f('B')
for x in l:
print x
编辑:正如其他人所指出的,这个问题是重复的。简短的回答是python仅在程序启动时评估默认参数一次,并将结果静态存储在函数中。从C ++开始,我希望每次调用函数时都会对它进行求值,并且只在本地存储而不是静态存储。
在我的代码中,我看到了这种行为的两种危险情况:A)函数应该修改一个列表,但如果在函数调用时没有传递参数,它应该以空列表开头。现在我遇到的问题是列表越来越多了。
解决方案是a)删除参数的默认值,以便我被迫至少提供一个空列表:
def f( x, y):
result = y
result.append(x+'1')
return result
l = f('A',[])
l = f('B',[])
b)使用None作为默认参数:
def f( x, y=None):
result = y or []
result.append(x+'1')
return result
B)另一个问题是默认参数是在程序启动时计算的,我使用了now的时间戳作为默认参数...
result = y
使名称result
和y
指向内存中的相同对象,因此第二次调用中的列表y
将不为空(因为现在对result
的任何修改也将出现在y
中(在您的情况下,您将附加到它) ),试试这个(列表切片),它会给你你想要的输出:
result = y[:] # elements of y, from the first to the last
这个切片相当于值中的result = y
,但result
和y
将指向内存中的两个不同对象,因为切片会创建一个新列表。