内置数据类型int,float,bool,str,tuple 是不可变对象, 字典,集合,列表是可变对象。
在定义python函数时,千万不要使用可变类型对象作为函数的默认参数,那样会引发意想不到的错误,下面的代码向你展示这种错误
def add_int(value, data=[]):
data.append(value)
return data
result = add_int(3)
print(result) # [3]
我定义了一个add_int函数,默认参数data是一个列表,程序执行结果是[3], 看起来没有什么问题,但是在第2次执行add_int函数时,就会出现意想不到的情况
def add_int(value, data=[]):
data.append(value)
return data
result = add_int(3)
print(result)
result = add_int(4)
print(result)
程序输出结果是
[3]
[3, 4]
第2次输出的结果并不是预期的[4], 而是包含了第一次调用函数add_int函数时传入的参数3,这究竟是怎么一回事呢?
在定义函数时,默认参数只会被计算一次,而不是每次调用函数的时候才计算。python脚本在执行过程中,遇到函数定义的代码,会进行编译,创建一个代码对象,完成编译后,python会将默认参数存储在函数对象之中,准确的说是存储在__defaults__属性中,此后每次调用函数所使用的默认参数都是最开始计算的那一个,而由于这个默认参数是可变对象,所以会导致上面所描述的诡异问题。
def add_int(value, data=[]):
data.append(value)
return data
print(add_int.__defaults__)
通过输出__defaults__, 我们可以参看函数的默认参数,程序输出结果是一个元组([],) , 刚刚定义完的函数里,默认参数data还是一个空列表,执行过一次以后,就发生变化了
def add_int(value, data=[]):
data.append(value)
return data
print(add_int.__defaults__)
add_int(3)
print(add_int.__defaults__)
程序输出结果
([],)
([3],)
QQ交流群: 211426309