当咱们在构建一个函数或者方法时,若是想使函数中的一个或者多个参数使可选的,而且有一个默认值,那么能够在函数定义中给参数指定一个默认值,而且放到参数列表的最后就好了。好比:python
def func(a, b=42): print(a, b) func(1) #a=1, b=42 func(1,2) #a=1, b=2
若是默认参数使一个能够修改的容器,好比一个列表,集合或者字典,可使用None做为默认值。好比:app
#使用列表list做为默认值 def func(a, b=None): if b is None: b = [] ···
可是,若是你并非想提供一个默认值,而仅仅知识想测试下某个默认参数是否是有值传递进来,能够这样写:函数
_no_value = object() def func(a, b=_no_value): if b is _no_value: print("b没有值") else: print(a, b) func(1) # b没有值 func(1, None) # 1 None
仔细经过测试能够发现,传递一个None值和不传值两种状况是有差异的。测试
默认参数的值仅仅在函数定义的时候赋值一次,示例代码以下:spa
x = 42 def func(a, b=x): print(a, b) func(1) #1 42 x = 23 func(1) #1 42
从上面例子中能够看出,当咱们改变x的值的对默认参数值并无影响,这是由于在函数定定义的时候就已经肯定了它的默认值了。code
默认参数值的类型应该是不可变对象,好比None,True,False,数字或字符串,而不能使用列表,字典等可变类型。对象
不要像下面这样写代码:blog
def func(a, b=[]): #不能这么写 ···
若是这样写了,当默认值在某些地方被修改以后,程序就会出现问题。字符串
这些被修改的程序会影响到下次调用这个参数时的默认值。好比:it
def func(a, b=[]): return b x = func(1) print(x) #[] x.append("a") x.append("b") print(x) #['a', 'b'] y = func(1) print(y) #['a', 'b']
能够看到,b的默认值从一个空list,变成了[“a”, “b”],这种不会是你想要的默认参数。
为了不这种状况的发生,最好是将默认值设置为None,而后在函数里面检查它。
可是在将默认值设置为None以后,测试None值时使用is操做符是很重要的,is是这种方法的关键点。
有人可能会这样写:
def func(a, b=None): if not b: b = [] ···
这么写有有一个问题,就是虽然None确实会被当成False,可是还有其余的对象(好比长度为0的字符串,列表,元组,字典等)都会被看成False。所以上面的代码会误将一些其余输入也会看成没有输入。好比:
def func(a, b=None): if not b: b = [] return b print(func(1)) # [] print(func(1, [])) # [] print(func(1, 0)) # [] print(func(1, "")) # []
从结果中就能够看到,b的值并无发生改变,这不是咱们想要的结果。
当一个函数须要测试某个可选参数是否被使用者传递进来。这个时候须要当心的是不能用某个默认值,好比None,0或者False值来测试用户提供的值(由于这些值都是合法的值,是可能被用户传递进来的)。
你能够建立一个独一 无二的私有对象实例,就像上面的_no_value变量同样。在函数里面,你能够经过检查被传递参数值跟这个实例是否同样来判断。
这里的思路就是用户不可能去传递这个_no_value实例做为输出。所以这里经过检查这个值就能肯定某个参数是否被传递进来了。