list.clear()与list = []有什么不同?

unt*_*led 7 python python-3.x

函数的预期目标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 = []不编辑(在这种情况下清除)列表,而追加和清除呢?

Sha*_*ger 7

bar = [] 重新开始 bar ; 它会创建一个全新的空list,并将名称绑定bar到它.bar以前的事情并不重要; 它可能是一个int,一个tuple,或者dict,它现在无关紧要,因为它现在必然是一个全新的list.旧的绑定在当前方法调用中不再存在,但原始的list 仍然存在作为默认参数的值foo(注意:由于这种混淆,可变默认值被认为是令人惊讶和丑陋的).

bar.clear()呼吁的方法存在的 list,它告诉list清除本身(对什么没有影响bar是指,它最好是一些clear方法,但除此之外,它不是真正需要的,这是一个list).因为它 bar你开始时相同(引用在函数默认值中缓存的相同的可变默认值),这会影响你将来的调用(因为bar继续引用list你提供的可变默认值).