函数参数的匹配原则
位置:从左至右进行匹配
一般情况下,是通过位置进行匹配,把参数值传递给函数头部的参数名称,匹配顺序为从左到右。
关键字参数:通过参数名进行匹配
调用者可以定义哪一个函数接收这个值,通过在调用的时候使用参数的变量名,使用name=value这种语法。
默认参数:为没有传入值的参数定义参数值
如果调用时传入的值过于少的话,函数能够为参数设定默认的参数值,使用name=value这种语法。
可变参数:接收任意多基于位置或关键字的参数
函数能够使用特定的参数,它们是已字符*开头,接收任意多的额外参数(这个特定常常叫做可变参数)
可变参数解包:传递任意多的基于位置或关键字的参数
调用者能够再使用*语法去将参数集合打散,分成参数。这个“*”与在函数头部的“*”恰恰相反:在函数头部它意味着收集任意多的参数,而在调用者中意味着传递任意多的参数。
匹配语法
函数参数匹配表1
语法 | 位置 | 解释 |
fun(value) | 调用者 | 常规参数:通过位置进行匹配 |
fun(name=value) | 调用者 | 关键字参数:通过位置进行匹配 |
fun(*sequence) | 调用者 | 以name传递所有的对象,并作为独立的基于位置的参数 |
fun(**dict) | 调用者 | 以name成对的传递所有的关键字/值,并作为独立的关键字参数 |
def fun(name) | 函数 | 常规参数: 通过位置或变量名进行匹配 |
def fun(name=value) | 函数 | 默认参数值,如果没有在调用中传递的话 |
def fun(*name) | 函数 | 匹配并收集(在元组中)所有包含位置的参数 |
def fun(**name) | 函数 | 匹配并收集(在字典中)所有包含关键字的参数 |
这些特殊的匹配模式分解到如下的函数调用和定义中:
- 在函数调用中(在表中前4行),简单的通过变量名位置进行匹配,但是使用name=value的形式告诉python依照变量名进行匹配,这些叫做关键字参数。在调用中使用*sequence或者**dict允许我们在一个序列或字典中相应地封装任意多的位置相关或者关键字对象,并且在将它们传递给函数的时候,将它们解包为分开的、单个的参数。
- 在函数头部,一个简单的变量名是通过位置或者变量名进行匹配的(取决于调用者是如何传递参数给它的),但是name=value的形式定义了默认的参数值。*name的形式收集了任意的额外不匹配的参数到元组中,并且**name的形式将会收集额外的关键字参数到字典中
示例:
##调用关系中的*和**参数,匹配表1的3、4行 #*参数 >>> def fun2(a,b,c,d):print a,b,c,d ... >>> fun2(1,2,*(3,4)) 1 2 3 4 #**参数 >>> def abc(a=1,b=2,c=3): ... print a,b,c ... >>> abc({‘a‘:10,‘b‘:20,‘c‘:30}) {‘a‘: 10, ‘c‘: 30, ‘b‘: 20} 2 3 >>> abc(**{‘a‘:10,‘b‘:20,‘c‘:30}) 10 20 30
细节
如果决定使用并混合特定的参数匹配模型,python将会遵循下面的原则:
- 在函数调用中,参数必须以此顺序出现:任何位置参数,后面跟着任何关键字参数(name=value)和*sequence形式的组合,后面跟着**dict形式。
- 在函数(定义)头部,参数必须以此顺序出现:任何一般参数(name),后面紧跟着默认参数(name=value),如果有的话,后面是*name的形式, 后面跟着**name形式。
示例:
>>> def func4(a,b,c=1,*args,**kwargs):print a,b,c,args,kwargs ... >>> func4(1,2,*(3,4),**{‘c‘:11,‘d‘:22}) Traceback (most recent call last):#见解释2 File "<stdin>", line 1, in <module> TypeError: func4() got multiple values for keyword argument ‘c‘ >>> func4(1,2,*(3,4),**{‘aa‘:11,‘d‘:22}) 1 2 3 (4,) {‘aa‘: 11, ‘d‘: 22}#见解释1
解释:
1,在函数调用中*args中的值会优先匹配位置参数,剩下的才会放到args变量中;
2,调用时,**kwargs中不能包含已经赋值的位置参数的名称,除非此位置参数未赋值;
在调用和函数头部中,如果出现**kwargs的话,都必须出现在最后。如果你使用任何其他的顺序混合了参数,你将会得到一个语法错误,因为其他顺序的混合会产生歧义。
python内部是使用一下步骤来在赋值前进行参数匹配的:
1,通过位置分配非关键字参数。
2,通过匹配变量名分配关键字参数。
3,其他额外的非关键字参数分配到*args元组中。
4,其他额外的关键字参数分配到**kwargs字典中。
5,用默认值分配给在头部未得到分配的参数。
示例:
##综合调用 >>> def fun3(a,b,*args,**kwargs): ... print a,b,args,kwargs ... >>> fun3(3,4,5,6,7,8,x=10,y=20) 3 4 (5, 6, 7, 8) {‘y‘: 20, ‘x‘: 10}
参考:《python学习手册》(第四版),修改了部分语句和错误,并添加示例
时间: 2024-10-06 14:45:30