我是新人。下面是python文档中的一个示例
def funtest(num, L=[]):
L.append(num)
return L
print(funtest(2))
print(funtest(3))
print(funtest(4))
我认为每个函数调用都应该执行相同的事情,这意味着在每个函数调用中L=[]。所以我认为输出应该是这样的:
[2]
[3]
[4]
但真正的答案在下面。看起来funtest()继承了上次函数调用的输出。然后不断地将其传递给下一个函数调用。我弄糊涂了
[2]
[2, 3]
[2, 3, 4]
当我将代码更改为以下情况时:
def funtest(L=[]):
L.append(L)
return L
print(funtest([2]))
print(funtest([3]))
print(funtest([4]))
实际输出如下所示:
[2, [...]]
[3, [...]]
[4, [...]]
输出与前一个有很大不同。我现在更糊涂了。有人修复我的精神创伤吗?非常感谢
问题是L的默认值是一个可变对象(在您的例子中是一个空列表)。
Python中的默认值在函数定义时计算
每次调用该函数时,都会得到相同的默认值,如果向对象(列表)添加任何内容,则会得到以前添加的所有内容
获取默认列表(或字典或集合)的正确方法是在函数内部的运行时创建它。
这是Python中初学者开发人员的常见错误
您想阅读类似的问题:
"Least Astonishment" and the Mutable Default Argument
Good uses for mutable function argument default values?
为了解释发生了什么
第一个案例
因此python函数中的默认值仅在定义函数时实例化一次,因此列表仅在定义函数时创建,并且您不断向其中添加,因此现在结果包含所有旧值
对于在python中用作参数默认值时可变的所有值,都是如此
你能做什么
通常使用不可变值,对于list,使用
None
作为默认值,在函数中检查list是否为None
,并在函数中创建一个空列表在这里阅读更多内容(第一个问题):https://docs.python-guide.org/writing/gotchas/
第二种情况
现在,当您执行
L.append(L)
操作时,实际上是通过将相同的列表附加到自身来创建无限列表每当列表太大而无法打印时,python就会在其位置显示这三个点
在这里阅读更多What does [...] (an ellipsis) in a list mean in Python?
将L移到函数内部
这将重新设置L
相关问题 更多 >
编程相关推荐