因为:
1、Python 和很多语言一样,变量(包括函数变元)是引用语义的,即变量是对实际对象的一个引用(或者说绑定),对变量的赋值(包括传参)也不会新建一个对象,而是把变量重新引用(绑定)到等号右边的新对象上。
2、函数的默认参数的求值,是在定义时一次进行,而不是在每次调用时都进行。
所以:
函数 fun 的默认参数 lst 在定义时求值后,不传参时变元 lst 就绑定到同一个列表对象 [] 上了,后续的任何操作都不会影响这个绑定。那么,每次不传参的函数调用,函数体操作的 lst 都是指向同一个列表对象。
把变量和对象有意识地区分开来对于引用语义的语言是非常必要的,否则会有某些反直觉的结果。当然这一般也需要专业训练。相比之下,C 语言(或者 Go)这种变量是值语义的语言其实更直观一些,指针类型把对象的引用摆到明面上了。
回到问题本身,你无法改变 Python 的传参语义,通常的解决办法是针对前面的特性 2,可以把默认参数设置为 None 之类容易识别的值,然后实际的对象定义放在函数体里面。
【 在 lilnelse (不折腾) 的大作中提到: 】
: 在一本书上看到一个例子
: def fun(lst=[]):
: lst.append('a')
: ...................
--
FROM 114.249.196.*