首页 > 其他 > 详细

函数默认参数

时间:2021-05-21 09:31:21      阅读:23      评论:0      收藏:0      [点我收藏+]

不可变对象作为默认参数

一般来说,函数的默认参数都用不可变对象来作默认参数,如int,str,None,tuple,bool等。

举例:

def func(x,y=2):
   return x+y
func(1)
>>>print(func(1))
3
>>>print(func(1,10))
11

在实际工程中,经常会用None和bool来作默认参数,在使用None作默认参数的时候,函数内部的判断务必用:if param is None 或者 if parma==None都可以,None是一种特殊的类型Nonetype, 通过is比较id地址或者通过==比较值,都可以准确判定。但是不要使用if not param:,因为除了None,空字典,空字符,空列表等也会通过判定,无法被过滤掉。

举例:

def func(y=None):
   if not y:
       print(‘10000‘)
   else:
       print(‘ttttt‘)
>>>func(1)
ttttt
>>>func()
10000
>>>func([])
10000
>>>func(‘‘)
10000
>>>func({})
10000
?

因此对None的判定不要用not。

 

可变对象作为默认参数

一般不要用可变对象作为默认参数,后续如果对可变对象进行了增删改,会不断影响到下一次调用时默认参数的值。举例:

def func(x,y=[1]):
   return y
>>>m=func(1)
>>>m
[1]
>>>n=func(1,[1,2,3])
>>>n
[1, 2, 3]  ###到这里都没有任何问题
?
#这里去改变之前的m
>>>m.append(4)
>>>m.append(‘test‘)
>>>m
>>>[1, 2, 3, 4, ‘test‘]
?
#重新去调用函数,发现这个时候里面的默认参数y已经跟着改了
>>>q=func(1)
>>>q
[1, 2, ‘test‘]

因此,默认参数用可变对象非常容易造成代码出现预期之外的问题。

什么原因?

本质原因就是赋值,浅拷贝,深拷贝之间的问题。上述例子的本质流程:

m=y

m.append(4)

m.append(‘test‘)

因为y是可变对象,赋值操作只是类似取了一个别名,两个变量存的地址id一样,即都是引用的对象[1],当对象内部变了,回来会同时影响m和y。

def func(x,y=[1]):
   print(id(y))
   return y
>>>m=func(1)
2665443856192
>>>print(id(m))
2665443856192

 

如果实在想用某个可变对象做默认参数怎么办?比如在最近一个项目中,一个类的入参我想传如一个list,但这个list又想用[0]来作为默认参数,可以这样实现:

def func(x:int,y=None):
   if y is None:
       y=[0]
   else:
       if not isinstance(list,type(y)):      
           raise Exception(‘y must be list!‘)
   return y
?
>>>print(func(1))
0
>>>func(1,[1,2,3])
[1,2,3]
>>>func(1,1)
Traceback (most recent call last):
 File "<input>", line 11, in <module>
 File "<input>", line 7, in func
Exception: y must be list!

 

函数默认参数

原文:https://www.cnblogs.com/qianfanwaer/p/14792106.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!