关于python:为什么默认参数表现为全局不可变?

Why the default argument behaved globally immutable?

python中的default arguments直观地是局部作用域但全局可变的变量。

下面,为什么第二次调用my_sum的结果是20,尽管我希望它是30

1
2
3
4
5
6
7
8
9
10
11
def my_append(el, ar = []):
  ar.append(el)
  return ar
print my_append(10) # => [10]
print my_append(20) # => [10, 20]

def my_sum(i, sum = 0):
  sum += i
  return sum
print my_sum(10) # => 10
print my_sum(20) # => 20


为了有助于澄清这一点,请考虑这一行更改:

1
2
3
4
5
6
7
def my_append(el, ar=[]):
    ar = ar + [el]
    # ar.append(el)
    return ar

print(my_append(10))  # [10]
print(my_append(20))  # [20]

因此,问题不在于可变性或不可变性,而在于第二个版本重新命名了名称。

这是一个比评论家们所说的更微妙的问题。int.__iadd__不存在,因此在整数的情况下,操作返回到sum = sum + i时,再次重新绑定名称。

然而,list.__iadd__确实存在,它使现有的对象发生变异。这就是您看到默认参数发生更改的原因。