python五类参数:位置参数,关键字参数,默认参数,可变位置或关键字参数的使用。
def f(a,*b,c=10,**d): print(f'a:{a},b:{b},c:{c},d:{d}')
默认参数c
不能位于可变关键字参数d
后.
调用f:
In [10]: f(1,2,5,width=10,height=20) a:1,b:(2, 5),c:10,d:{'width': 10, 'height': 20}
可变位置参数b
实参后被解析为元组(2,5)
;而c取得默认值10; d被解析为字典.
再次调用f:
In [11]: f(a=1,c=12) a:1,b:(),c:12,d:{}
a=1传入时a就是关键字参数,b,d都未传值,c被传入12,而非默认值。
注意观察参数a
, 既可以f(1)
,也可以f(a=1)
其可读性比第一种更好,建议使用f(a=1)。如果要强制使用f(a=1)
,需要在前面添加一个星号:
def f(*,a,**b): print(f'a:{a},b:{b}')
此时f(1)调用,将会报错:TypeError: f() takes 0 positional arguments but 1 was given
只能f(a=1)
才能OK.
说明前面的*
发挥作用,它变为只能传入关键字参数,那么如何查看这个参数的类型呢?借助python的inspect
模块:
In [22]: for name,val in signature(f).parameters.items(): ...: print(name,val.kind) ...: a KEYWORD_ONLY b VAR_KEYWORD
可看到参数a
的类型为KEYWORD_ONLY
,也就是仅仅为关键字参数。
但是,如果f定义为:
def f(a,*b): print(f'a:{a},b:{b}')
查看参数类型:
In [24]: for name,val in signature(f).parameters.items(): ...: print(name,val.kind) ...: a POSITIONAL_OR_KEYWORD b VAR_POSITIONAL
可以看到参数a
既可以是位置参数也可是关键字参数。