python函数的默认参数为什么不可以定义可变类型
这篇文章主要介绍“python函数的默认参数为什么不可以定义可变类型”,在日常操作中,相信很多人在python函数的默认参数为什么不可以定义可变类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python函数的默认参数为什么不可以定义可变类型”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
函数的默认参数请勿定义可变类型经常会看到这样一句代码警告:
Default argument value is mutable
意思是告诉我们函数的定义中,使用可变类型做默认参数。
那为什么会有这个警告呢?
可变类型和不可变类型可变类型(mutable):列表,字典
不可变类型(unmutable):数字,字符串,元组
定义可变类型会有什么问题?deffun(a=[]):a.append(1)print(a)if__name__=="__main__":fun()fun()>>>[1][1,1]
可以发现,默认参数定义可变类型之后,在第二次乃至更多次地调用同一个函数时,默认参数仿佛失去了效果。
此时,在需要重复调用同一个函数的场景中,就非常容易导致问题,并且该问题不易察觉。在debug的时候就会表现成明明没有参数传进来,但是函数参数会有值,并且执行了不应该执行的操作。
导致的原因我的理解:
我们定义的函数本身是一个function的实例化对象,每当我们进行函数的定义时,就是创建了一个function的实例化对象,而默认参数就是其属性。
在没有传入参数,以默认参数形式调用,并且改变了函数对象的属性值时,改变的属性值被保存下来,当第二次调用同一个对象时,属性值已经发生了改变。
type(fun)>>>function解决方法
deffun(a=None):ifaisNone:a=[]a.append(1)print(a)if__name__=="__main__":fun()fun()>>>[1][1]关于可变类型作为默认参数时的注意点
请先看代码,看看代码的输出是否和你想的一样。
defe(v,l=[]):l.append(v)returnll1=e(10)l2=e(123,[])l3=e("a")print(l1,l2,l3)#输出:([10,'a'],[123],[10,'a'])
关于上述代码,标准解释是:带有默认参数的表达式在函数被定义的时候被计算,不是在调用的时候计算。
我觉得通俗的解释是:当不传默认值的时候,无论调用多少次该函数,在函数体内部使用的一直都是那个默认的“l”,而这个默认的“l”又是可变类型,所以,它的改变会影响所有指向它的变量,也就是l1和l3。
为了使以上两点的观点更加站的住脚,我进行以下几个测试。
测试:将可变类型列表换为字典defe(k,v,d={}):d[k]=vreturndd1=e(10,10)d2=e(123,123,{})d3=e("a","a")print(d1,d2,d3)#输出:({'a':'a',10:10},{123:123},{'a':'a',10:10})测试:来个不可变类型字符串
defe(v,s=""):s=s+vreturnss1=e("我")s2=e("a","")s3=e("是")print(s1,s2,s3)#输出:我a是
其实以上类型都已经说明问题了,但是写个文章不容易,我决定用元祖包列表,看看修改这个列表中的数据会怎样。
实际上是不用测试的,最终打印出来的数据一定是类似**“可变类型时的操作”**时的输出的。
为什么?因为我没有修改元祖本身,修改的是其可变类型列表啊。
不能扯远了,不然扯到深拷贝,浅拷贝了。
测试:元祖包个列表来defe(v,t=([],)):#传递有元素的元祖的时候要记得带逗号哦。t[0].append(v)#t=t[0].append(v)要知道t[0].append(v)是没有返回值的,t会指向None,如果这样返回,外部打印的全部为None,所以不可以这样返回。#而且如果你想t[0]=t[0].append(v)也是不行的,为啥?你在ipython中输入dir(())你就知道了。#好吧,其实是因为元祖是可读不可写的。它能切片、遍历就已经很不错了。。。。。returntt1=e("我")t2=e("a",([],))t3=e("是")print(t1,"\n",t2,"\n",t3)#输出:#(['我','是'],)#(['a'],)#(['我','是'],)
到此,关于“python函数的默认参数为什么不可以定义可变类型”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。