龙空技术网

「Python」正确使用函数参数默认值

暖冬2000 185

前言:

如今姐妹们对“默认值代码”大概比较关心,你们都想要了解一些“默认值代码”的相关内容。那么小编在网络上搜集了一些对于“默认值代码””的相关知识,希望咱们能喜欢,我们快快来学习一下吧!

Python语言的函数定义中,允许为参数定义默认值。例如:

def func(arg1,arg2=0,arg3=""):    pass

上述定义中为函数func的参数arg2,arg3指定了默认值。在调用func函数时,如果不指定这些参数的值,将使用默认值。

函数默认值为我们编写代码带来很多方便。不过,如果使用不当也会造成令人困惑的错误。我们来看下面的代码。

#使用数值packwith将列表填充至长度为lengthdef packlist(packwith,length,arr=[]):    n = length - len(arr)    if n>0:        arr.extend([packwith for i in range(n)])            return arrprint("list1 =",packlist(3,5))print("list2 =",packlist(1,10))print("list3 =",packlist(0,10,[1,2,3,4,5,6]))

这段代码的意图是将一个列表用一个固定数值填充至指定长度。

例如:

packlist(3,5)期望返回一个长度为5,元素都为3的列表[3,3,3,3,3];

packlist(1,10)期望返回一个长度为10,元素都为1的列表[1,1,1,1,1,1,1,1,1,1];

packlist(0,10,[1,2,3,4,5,6])则返回一个列表[1,2,3,4,5,6,0,0,0,0]。

而实际运行结果是这样的:

list1 = [3, 3, 3, 3, 3]

list2 = [3, 3, 3, 3, 3, 1, 1, 1, 1, 1]

list3 = [1, 2, 3, 4, 5, 6, 0, 0, 0, 0]

可以看到, packlist(1, 10)返回的结果与预期的并不一样。期望得到列表[1,1,1,1,1,1,1,1,1,1],而实际得到的是[3,3,3,3,3,1,1,1,1,1]。很明显是将上一次的运行结果作为默认值继续使用了。

为什么会出现这种情况呢?因为函数的默认值只在函数定义时创建一次,而不是在每次调用时创建一个新的对象。对于不可变对象(数值、字符串、元组、None),改变意味着创建新的对象,所以不会出现问题。而对于可变对象如列表,当对象做了改变后,后续调用使用默认值时仍会使用改变过的对象,就会产生不可预料的错误。所以,一般情况下,可变对象的参数默认值应定义为None. 上述代码可改为如下:

def packlist(packwith,length,arr=None):    if arr is None:        arr = [] #创建一个新的列表对象        n = length - len(arr)    if n>0:        arr.extend([packwith for i in range(n)])            return arrprint("list1 =",packlist(3,5))print("list2 =",packlist(1,10))print("list3 =",packlist(0,10,[1,2,3,4,5,6]))

这样代码就会输出符合预期的结果:

list1 = [3, 3, 3, 3, 3]

list2 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

list3 = [1, 2, 3, 4, 5, 6, 0, 0, 0, 0]

上面说了,一般情况下,可变对象的参数默认值应定义为None;当然在不一般的情况下,也可以定义成可变对象,例如将默认参数作为缓存使用。

# 通过姓名查找ID号def lookup_id(name,*,_cache={}):    id = None    if name in _cache:        id =  _cache[name]    else:        #从数据库中查找        id = lookup_from_db(name)        _cache[name] = id        return id

上述代码利用_cache的默认值,将每次调用得到的结果存放到_cache对象中, 从而减少数据库的查询。

标签: #默认值代码 #函数中带默认值的参数必须位于