函数1
def f(a, b=[]):
b.append(a)
print(b)
f(1,[3])
f(2,[4])
输出结果
[3, 1]
[4, 2]
函数2
def f(a, b=[]):
b.append(a)
print(b)
f(1)
f(2)
期望结果
[1]
[2]
最终结果
[1]
[1, 2]
运行结果分析
相同的函数在传参的方式不同时居然会导致运行结果出现bug,函数2因为没有传第二个参数,导致运行结果不是期望的值。
有很多人认为这是python语言不够严谨,在语言设计层面的bug。
首先看一下python的语言特点:
- 在python中一切都是对象,函数、字符、模块、类等等都是对象。
- 在python中,
类型属于对象,变量是没有类型的,这正是python的语言特性。所有的变量都可以理解是内存中一个对象的“引用” - 在python的数据类型中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象
- 不可变对象修改值得时候会引起内存地址的变化,而可变对象不会
现在分析一下:
函数2def f(a, b=[])中参数bb=[]指向的是一个空的列表对象,而且两次操作参数b没有指向新的列表对象,所以导致两次操作作用在同一个空列表对象上。
函数1虽然参数bb=[]指向的是一个空的列表对象,但是两次操作中参数b分别指向了不同的列表对象[3]和[4],导致两次操作作用于两个不同的对象。