下面这段代码的输出结果是什么?请解释。
| 1 | 
 | 
上面代码输出结果将是:
| 1 | list1 = [10, 'a'] | 
很多人都会误认为 list1=[10],list3=['a'],因为他们以为每次 extendList 被调用时,列表参数的默认值都将被设置为 [],但实际上并不是这样,新的默认列表在函数被定义的那一刻只会创建一次。
当 extendList 被调用时,如果没有指定特定参数,默认的 list 的值随后将被使用。这是因为默认值参数会在函数被定义的时候被创建和计算,而不是在被调用的时候被创建和计算。因此 list1 和 list3 指向的是同一个对象,也就是默认列表。而 list2 是函数被调用时另外指定了一个对象,而不是使用默认的。
画图来分步理解一下:
| 1 | def extendList(val, list=[]): | 
定义函数,设置位置参数 val,默认参数 list 指向空列表。

| 1 | list1 = extendList(10) | 
调用函数 extendList,并使用默认参数 list,函数执行过程中向列表中追加元素。空列表追加元素后,第一个位置指向了 10

| 1 | list2 = extendList(123, []) | 
调用函数 extendList,指定了另外一个空列表作为参数,而不是使用默认参数 list。函数执行过程中向手动指定的空列表中追加元素 123 。

| 1 | list3 = extendList('a') | 
调用函数 extendList,并使用默认参数 list,此时默认参数 list 所指向的列表已经有了元素,函数执行过程中向列表中追加元素,列表中的第二个位置指向了 'a' 。

所有的操作已经执行完,接下来进行打印输出。此时的 list1 和 list3 指向了同一个列表对象,即定义函数时的默认列表。而 list2 指向的是它调用函数时手动传给函数的另一个列表对象。
| 1 | print("list1 = %s" % list1) | 
于是输出结果就是:
| 1 | list1 = [10, 'a'] | 
我们可以在函数中使用 id() 方法获取函数操作的 list 的内存地址来验证操作的是否是同一个对象:
| 1 | def extendList(val, list=[]): | 
执行结果:
| 1 | 140494594992264 | 
 
        