为什么哩,如果你不使用不可变参数就会出现神の罰… 开玩笑的,如果使用可变参数的话可能会导致在后来的调用中得到的结果与预想结果不一样的问题 举个栗子:
>>> def add_a(L=[]): ... L.append('a') ... return L ... >>> add_a() ['a'] >>> add_a() ['a', 'a'] >>> add_a() ['a', 'a', 'a']咦,这是怎么回事哩,怎么一直在增加,其实是因为我们定义的默认参数是一个list(可变参数) 在定义函数的时候,参数 L 就已经被计算出来了,即 [] ,因为默认参数 L 是个可变参数,指向对象 [],每次调用该函数,如果改变了 L 的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的 [] 了。(我感觉是这样的,list是引用类型,是可变的,L指向的不是[]而是存储[]的地址,无论这个地址的内容怎么变,L都是指向这个地址的,所以说在第一次调用后[]变成了[‘a’],但是他的地址并没有改变,所以L还是指向他也就是[‘a’])
参数前面加*号就是可变参数的定义,参数 args 接收到是一个tuple,在函数调用的时候可以传入任意个参数包括0个 如果已经有了一个list或者tuple怎么办呢,可以用下面的这个方法
>>> l = [1,2,3] >>> my_sum(l[0],l[1],l[2]) 6当然啦,也有更简单的方法就是在参数前面加个*
>>> l = [1,2,3] >>> my_sum(*l) 6关键字参数呢,顾名思义,就是要给参数定义一个关键字,emmmm 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict,例:
>>> def student_info(name,age,**info): ... print('name:',name,'age:',age,'info:',info) ... >>> student_info('marco',16) name: marco age: 16 info: {} >>> student_info('monica',17,gender='girl') name: monica age: 17 info: {'gender': 'girl'}关键字嘛,说白了就是键值对啦,也就是说可以直接传入一个dict,只需要在参数前加**
>>> infos = {'gender':'boy','city':'BeiJing'} >>> student_info('Jack',16,**infos) name: Jack age: 16 info: {'gender': 'boy', 'city': 'BeiJing'}值得注意的是,传进去的参数**info的改动并不会影响到函数外的infos,这是因为info得到的是infos的一份拷贝.
这是一个挺有意思的参数,具体是这样使用的
>>> def person(name,age,*,city,gender): ... print(name,age,city,gender) ... >>> person('Panny',23,city='ShangHai',gender='girl') Panny 23 ShangHai girlemmm…,当然了这个是可以跟别的一起混用的,例如可变参数
>>> def person(name,age,*args,city,job): ... print(name,age,args,city,job) ... >>> person('Panny',24,'girl','funny',city='ChengDu',job='teacher') Panny 24 ('girl', 'funny') ChengDu teacher当前面有可变参数时,再使用命名关键字参数就不用在前面加*号了 当然,命名关键字参数也可以有缺省值
>>> def person(name,age,*args,city='ChengDu',job): ... print(name,age,args,city,job) ... >>> person('Panny',24,'girl','funny',job='teacher') Panny 24 ('girl', 'funny') ChengDu teacher在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。 这个就不多做累述了,大家可以自己试一下,说个比较特别的 对于任意函数,都可以通过类似func(*args, **kw) 的形式调用它,无论它的参数是如何定义的
虽然参数组合可以有很多种可能,但还是不建议大家整的太复杂,使用的参数组合多了就意味着函数接口的可读性差,哇塞的代码永远都是那些让人一眼能看懂的代码,还有别忘了Python的初衷,代码的简洁之道.