马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 sunrise085 于 2020-3-30 14:42 编辑
在python编程中,我们经常会用到函数,对于函数的参数有的时候是带有默认值的,这样在调用函数的时候,若省去带默认值的参数,程序则会用默认值来代替对应的参数。话不多说,直接以例子来说话~~ 例程1:
def func01(mystring='我喜欢小甲鱼。'):
mystring+='那是不可能的!'
print('调用函数,mystring=',mystring)
func01()
func01()
程序运行结果:调用函数,mystring= 我喜欢小甲鱼。那是不可能的!
调用函数,mystring= 我喜欢小甲鱼。那是不可能的!
在这个例程中,我们的函数func01()的形参mystring是有默认值的,然后在函数中对mystring进行了修改,程序调用了两次func01(),每次调用都是对默认值"我喜欢小甲鱼。"的修改。两次调用函数的结果是一样的 。这与我们想象中的是一致的。我们再看一个例程,你会的呆意想不到的结果~~
例程2 def func02(mylist=[2]):
mylist.append(3)
print('调用函数,myslist=',mylist)
func02()
func02()
我们先猜一下程序的运行结果,函数被调用了两次,每次使用的参数都是函数默认值mylist=[2],在函数中向mylist后面添加一个元素3,因此两次调用函数的结果应该都是:调用函数,myslist= [2,3]
我们看一下。 程序运行结果:调用函数,myslist= [2,3]
调用函数,myslist= [2, 3, 3]
咦?这是怎么回事儿,为什么第二次使用默认参数调用函数的时候,程序用的不再是参数的默认值了?python出bug了吗? python没出错,原因是酱紫滴~~我们来分析一下这两个函数的不同之处。
func01()的参数是字符串string,func02()的参数是列表list。这两种类型的参数有什么区别呢?在参数传递过程中有什么不同吗? 这个还真有!
在python中,整型int、字符串string、列表list、集合set、字典dict等等都可称之为对象,而这些不同类型的对象是有区别的,可以分为两类:不可变类型对象和可变类型对象。数字numbers、字符串string、元组tuples等是不可变类型对象,列表list、字典dict、集合set等是可变类型对象。 不可变类型对象就是一旦生成,就不可更改的对象,而可变类型对象是生成之后可以进行增删改等修改操作的对象。
对于不可变类型对象的修改操作实际上是创建了一个新的对象,然后将变量名(即标签)贴在新的对象上,这样我们就以为是修改了该变量了。对于可变类型对象的修改操作就是对原对象的修改。
函数的默认值只会在程序加载模块并读取到该函数的定义时设置一次。
我们现在来理解一下这两个例程。
func01()的默认值参数是不可变类型对象,程序加载时对该函数的参数默认值进行一次定义,mystring='我喜欢小甲鱼。',之后每次使用默认参数调用的时候,mystring都是该值,然后在函数中修改mystring,实际上是创建了一个同名局部变量,进行的修改。因此每次调用执行结果都一样。
func02()的默认值参数是可变类型对象,程序加载时对该函数的参数默认值进行一次定义,mylist=[2],在使用默认值调用函数时,对该参数进行了元素添加,实际上就是修改了对象mylist。因此每调用一次就在列表后面添加一个元素[3]。 那么问题又来了!我若是打算每次调用的时候都是用同一个初始list应该怎么办呢?办法还是有滴~~就是使用None最为默认值,再把实际的默认值放在函数里面。
程序如下:
def func02(mylist=None):
if mylist is None:
mylist=[2]
mylist.append(3)
print('调用函数,myslist=',mylist)
func02()
func02()
程序运行结果:
调用函数,myslist= [2, 3]
调用函数,myslist= [2, 3]
以上就是个人对带有默认值的参数的一些理解,看了一些相关资料之后进行的整理。可能会有不足之处,希望大家多多交流,相互交流,一起讨论,共同进步!! |