一、函数参数默认值的定义
Python函数的参数默认值是指在定义函数时为某些参数设置的一个默认值,这样在函数调用时如果没有给这些参数传值,就会使用默认值。在Python中,默认参数是通过在参数名后面加上=和默认值来定义的。例如:
def func(a, b=1):
print(a+b)
上面的代码中,参数b的默认值是1,这意味着如果在调用函数时没有给参数b传值,那么函数会使用默认值1。
二、函数参数默认值错误的问题
虽然函数参数默认值很方便,但是在使用时也需要特别注意,不然就会出现一些错误。
1、默认参数不可变对象的问题
在使用默认参数时,需要特别注意默认参数是否是可变对象。如果默认参数是不可变对象(如数字、字符串、元组等),那么每次调用函数时都会使用相同的默认值,这可能不会产生问题。但是,如果参数是可变对象(如列表、字典等),那么每次调用函数时,都会使用同一对象作为默认值。
例如:
def func(a, b=[]):
b.append(a)
return b
print(func(1)) # [1]
print(func(2)) # [1, 2]
print(func(3)) # [1, 2, 3]
上面的代码中,参数b的默认值是一个空列表。当执行func(1)时,b被修改成了[1],这是预期行为。但是,当执行func(2)时,b的默认值已经是[1],所以执行后的结果是[1, 2],这并不是预期行为。当执行func(3)时,b的默认值是[1, 2],所以执行后的结果是[1, 2, 3]。
如果想在每次调用函数时都使用一个新的列表作为默认值,可以在函数中重新定义一个新的列表:
def func(a, b=None):
if b is None:
b = []
b.append(a)
return b
print(func(1)) # [1]
print(func(2)) # [2]
print(func(3)) # [3]
2、默认参数可变对象的问题
和前面提到的问题相反,如果默认参数是可变对象(如列表、字典等),那么每次调用函数时,都会使用同一对象作为默认值。这就可能会导致函数的不良行为。
例如:
def func(a, b={}):
b[a] = a
return b
print(func(1)) # {1: 1}
print(func(2)) # {1: 1, 2: 2}
print(func(3)) # {1: 1, 2: 2, 3: 3}
和第一个问题类似,当执行func(1)时,b的默认值是{},当执行func(2)时,b的默认值是{1:1},当执行func(3)时,b的默认值是{1:1, 2:2}。
要避免这个问题,可以使用不可变对象,如None或者传递一个新的列表或字典作为默认值:
def func(a, b=None):
if b is None:
b = {}
b[a] = a
return b
print(func(1)) # {1: 1}
print(func(2)) # {2: 2}
print(func(3)) # {3: 3}
三、总结
在使用函数参数默认值时,要特别注意默认参数是否是可变对象。如果默认参数是不可变对象,通常不会出现问题。但是如果参数是可变对象,需要特别小心,尽量使用不可变对象或者在函数中重新定义一个新的可变对象。