Python中定义函数时可以指定函数参数类型以满足不同需要,也可以将各种类型参数组合起来使用,十分灵活。不同类型参数各有特色,如果使用恰当可以丰富函数功能,使用者调用函数时也方便很多。但用法不当时也会造成很多麻烦,得不偿失。函数参数类型及特点:
1、位置参数
顾名思义,位置固定的参数,调用函数时需要一一对应为其赋值,不能不赋值,更不能不按设定类型赋值。
优点:用法简单,在函数定义时按顺序列在括号里就行。
缺点:不够灵活,必须知道每个参数类型及含义,为确保函数功能正常不得在函数中进行参数检查。
例:
def pos_para(a,b,c,d):
print(a,b,c,d)
2、默认参数
有些时候函数中某些参数存在默认值,或者为了简化调用过程可以省略不写,从而使用默认值运行函数。因此可以使用默认参数,默认参数用法是直接在定义函数时对其进行赋值。调用时如果没有特殊需要可以不对其再次赋值。需要注意的是默认参数必须在位置参数(如果有)后面声明。
优点:调用简单,没有特殊需求可以不赋值。
缺点:由于调用时省略赋值过程,默认参数为一个空的list时需要将其内容初始化为None,即一个无效的固定值,该值无特殊含义,只是因为Python特性如果没有初始化则“悬空”,如果在函数中为该list添加了成员,此list内容会保存在新创建的list中下次再调用时又会在这个list基础上增加新成员。
例(错误用法):
def default_para(L=[]):
L.append('endline')
return L
例(正确用法):
def default_para(L=[None]):
if L is None:
L = []
L.append('endline')
以上两种写法的主要区别就是正确用法用无意义值None对新建的list进行初始化,函数使用这种不可变的参数很有用,可以确保多个任务同时访问时也不会出错。
3、可变参数
可变参数也是为了简化使用过程,因为并未限制参数数量,使用起来十分灵活。可变参数的声明只需要在参数名前面加一个'*'即可,因此只需要一个参数就能实现接受多个赋值。可变参数将接收到的值存放于一个tuple中,再按照顺序进行使用。
优点:灵活,简化使用,参数数量较多直接赋值即可。
缺点:仍然需要检查输入类型是否符合设定。
例:
def variable_para(*para):
for n in para:
print(n)
4、关键字参数
"关键字"这个词可以让人联想到Python中的某种数据类型->dict,因此,关键字参数的作用就类似一个dict,调用时可以直接输入一个dict或者按照"key=value"的格式进行赋值。声明关键字参数时只需要在参数名前边加上"**"。
优点:可以扩展参数,在类似赋值对象的应用场景下很便捷。
缺点:必须按照dict的格式赋值,用途有限。不能限制输入参数。
例:
def key_para(**kw):
print(kw)
key_para(name='Thomas',age='18',gender='Male')
5、命名关键字参数
命名关键字参数是为了解决关键字参数不能限制输入参数的问题,如果不对输入参数进行限制,可能出现未知问题。命名关键字参数的声明很简单,只需要用"*"将其与其他参数隔开,并且置于其他参数之后。因为有参数名限制,调用时需要按照参数类型进行赋值,就避免了不受限参数带来的问题。
优点:限制参数范围,减少因关键字参数不受限造成的错误。
缺点:不够灵活。
例:
def named_key_para(a,b,*,name,age):
print(a,b,name,age)
6、参数组合
在Python中定义函数,可以用位置参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
例:
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。当然,也可以将前面几个参数加入tuple,将后面几个参数做成一个dict直接进行赋值。
para1 = (1,2,3,a)
para2 = {age = '18', gender = 'Male'}
f1(*para1,**para2)
para1 = (1,2,a)
para2 = {'d':123,'age':'#'}
f2(*para1,**para2)
虽然参数组合基本可以满足各种功能需求,但是用起来十分繁琐且容易出错,因此不建议在一个函数中使用太多组合。