前言:
如今姐妹们对“默认值代码”大概比较关心,你们都想要了解一些“默认值代码”的相关内容。那么小编在网络上搜集了一些对于“默认值代码””的相关知识,希望咱们能喜欢,我们快快来学习一下吧!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对象中, 从而减少数据库的查询。
标签: #默认值代码 #函数中带默认值的参数必须位于