函数的预期目标foo是将作为参数提供的数字添加到列表中,如果它为0,则重置列表.首先我写了这个程序:
def foo(n, bar = []):
if n == 0:
bar = []
print("list empty")
else:
bar.append(n)
for y in bar:
print(y, end=', ')
print()
foo(5)
foo(3)
foo(0)
foo(6)
Run Code Online (Sandbox Code Playgroud)
输出:
5,
5, 3,
list empty
5, 3, 6,
Run Code Online (Sandbox Code Playgroud)
但它看起来像bar = []被忽略了.然后我改变bar = []了bar.clear(),它按照我的想法运作:
def foo(n, bar = []):
if n == 0:
bar.clear()
print("list empty")
else:
bar.append(n)
for y in bar:
print(y, end=', ')
print()
foo(5)
foo(3)
foo(0)
foo(6)
Run Code Online (Sandbox Code Playgroud)
输出:
5,
5, 3,
list empty
6,
Run Code Online (Sandbox Code Playgroud)
我不明白,为什么bar.clear()从工作differntly bar = []自clear()应
从集合中删除所有元素.
所以同样的事情bar = [].
编辑:我不认为我的问题是"最小惊讶"和可变默认参数的重复,我知道
默认值仅计算一次.
(从官方教程)但我要问的是,为什么bar = []不编辑(在这种情况下清除)列表,而追加和清除呢?
bar = [] 重新开始 bar ; 它会创建一个全新的空list,并将名称绑定bar到它.bar以前的事情并不重要; 它可能是一个int,一个tuple,或者dict,它现在无关紧要,因为它现在必然是一个全新的list.旧的绑定在当前方法调用中不再存在,但原始的list 仍然存在作为默认参数的值foo(注意:由于这种混淆,可变默认值被认为是令人惊讶和丑陋的).
bar.clear()呼吁的方法存在的 list,它告诉list清除本身(对什么没有影响bar是指,它最好是一些有clear方法,但除此之外,它不是真正需要的,这是一个list).因为它与 bar你开始时相同(引用在函数默认值中缓存的相同的可变默认值),这会影响你将来的调用(因为bar继续引用list你提供的可变默认值).
| 归档时间: |
|
| 查看次数: |
159 次 |
| 最近记录: |