python的函数定义非常简单,把参数的名字和位置确定下来,函数的接口定义就完成了。但是灵活度却非常的大,比如:位置参数(包括默认参数)、可变参数、关键字参数、命名关键字参数。其中各种参数的定义方式也不同。
位置参数
位置参数,是平时做算法题最常用到的,调用函数时,在对应的位置填入对应的参数即可。此处不做赘述
例:
def my_abs(n):
if n>=0:
return n
else:
return -n
默认参数
默认参数,是对于一些不常做修改的参数,给它们赋一个默认值。当需要修改的时候,像位置参数一样在对应位置赋值即可;不需要修改时,使用默认值。
例:
def enroll(name,gender,age,city='Chengdu'):
print('name:',name)
print('gender:',gender)
print('age:',age)
print('city:',city)
当调用enroll函数时,可以传入3个参数,也可以传入4个参数。
当传入3个参数时,输入的city默认为Chengdu
当传入4个参数时,输出的city值为输入的city,如输入enroll(‘liang’,‘M’,‘18’,‘Beijing’),输出的city对应为Beijing
注意: 默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
可变参数
当我们输入的参数个数不确定的时候,例如要计算一个list中所有数之和。但是传入的每个list中数字的个数不一定相同。这时候就需要可变参数来定义函数参数。
例:
def list_sum(*args):
sum = 0
for num in args:
sum = sum + num
return sum
这个时候,list_sum函数可接收的参数个数就是可变的了,可以输入任意个数,这些数自动组装成一个tuple
*args是可变参数,args接收的是一个tuple;
关键字参数
与可变参数相似,可变参数允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
例:
def enroll(name,gender,**kw):
print('name:',name,'gender:',gender,'others':,kw)
给参数赋值:
>>> enroll('liang','m',age=18,city='chengdu')
输出:
name:liang gender:m {'age':18,'city':'chengdu'}
关键字参数可以扩展函数的功能。比如,在enroll函数里,我们保证能接收到name和gender这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查
继续考虑上一个用户注册的功能,如果用户提供了很多很多的参数,但是有一些并不是我们想要的,这个时候就需要限制用户的拓展功能,让他们只能在固定的参数下拓展或不拓展。
例:
def enroll(name,gender,*,age,city):
print('name:',name,'gender',gender,'age:',age,'city:',city)
调用
#命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错
>>> enroll('liang','m',age=18,city='chengdu')
输出
name:liang gender:m age:18 city:chengdu
命名关键字参数同样可以有缺省值
注意:如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了
def enroll(name,gender,*arg,age,city):
pass
此时,age和city仍旧是命名关键字参数
python函数的参数定义和调用是很灵活的,学以致用是最好的。