参数匹配顺序——Python学习之参数(三)
这篇博文是对上一篇博文 参数匹配模型的总结与扩展。
函数参数匹配表
下面的表格总结了Python中参数匹配的语法。
考虑到翻译过来可能不准确,我就不翻译成中文了。
参数匹配顺序
在函数调用中,参数必须以此顺序出现:任何位置参数,后面跟着任何关键字参数(name=value
)和*iterable
形式的组合,最后是**dict
形式。
在函数头部,参数必须以此顺序出现:任何一般参数(name
),紧跟着任何默认参数(name=value
),再然后是*name
,再再然后是 keyword-only 参数(name
或者name=value
),最后是**name
形式。
注意:在函数调用和函数头部中,如果出现**arg
形式的话,都必须出现在最后。
Python内部是按照以下的步骤在赋值前进行参数匹配的:
- 通过位置分配非关键字参数。
- 通过匹配变量名分配关键字参数。
- 其他额外的非关键字参数分配到
*name
元组中- 其他额外的关键字参数分配到
**name
字典中。- 用默认值分配给在头部未得到分配的参数。
keyword-only 参数的位置
在一个函数头部,keyword-only 参数必须编写在**arg
之前、*arg
之后(如果二者都有的话)。无论何时,一个参数名称出现在*arg
之前,它应该是默认位置参数,而不是keyword-only 参数。
>>> def f(a, *b, **d, c=6): print(a, b, c, d) # Keyword-only before **!
SyntaxError: invalid syntax
>>> def f(a, *b, c=6, **d): print(a, b, c, d)
>>> f(1, 2, 3, x=4, y=5) # Default used
1 (2, 3) 6 {'y': 5, 'x': 4}
>>> f(1, 2, 3, x=4, y=5, c=7) # Override default
1 (2, 3) 7 {'y': 5, 'x': 4}
>>> f(1, 2, 3, c=7, x=4, y=5) # Anywhere in keywords
1 (2, 3) 7 {'y': 5, 'x': 4}
>>> def f(a, c=6, *b, **d): print(a, b, c, d) # c is not keyword-only here!
>>> f(1, 2, 3, x=4)
1 (3,) 2 {'x': 4}
第1行的写法是错误的,如果c
是一个keyword-only 参数,那么它必须在*b
之后,**d
之前,即第3行那样。
第4行和第6行是函数调用,区别是第4行采用了参数c的默认值,第6行覆盖了默认值。
第12行,c=6
是一个带有默认值的位置参数,第13行的“2”覆盖了c的默认值。
在函数调用中,keyword-only 参数可以编写在*arg
之前或之后,也可能包含在**arg
中。
第1行,c 是一个带有默认值的keyword-only 参数。
>>> def f(a, *b, c=6, **d): print(a, b, c, d) # KW-only between * and **
>>> f(1, *(2, 3), **dict(x=4, y=5)) # Unpack args at call
1 (2, 3) 6 {'y': 5, 'x': 4}
>>> f(1, *(2, 3), **dict(x=4, y=5), c=7) # Keywords before **args!
SyntaxError: invalid syntax
>>> f(1, *(2, 3), c=7, **dict(x=4, y=5)) # Override default
1 (2, 3) 7 {'y': 5, 'x': 4}
>>> f(1, c=7, *(2, 3), **dict(x=4, y=5)) # After or before *
1 (2, 3) 7 {'y': 5, 'x': 4}
>>> f(1, *(2, 3), **dict(x=4, y=5, c=7)) # Keyword-only in **
1 (2, 3) 7 {'y': 5, 'x': 4}
第5行,c=7
应该出现在 **dict(x=4, y=5)
之前;
第8和11行,c=7
可以出现在 *(2, 3)
之后或之前;
第14行,c=7
可以出现在**dict(x=4, y=5, c=7)
中。
【本系列完】
前两篇文章分别是:
参数匹配模型——Python学习之参数(二)
Python学习之参数(一)
参考资料
《Python学习手册(第4版)》,机械工业出版社
《Learning Python 5th Edition》, O’Reilly