共计 1927 个字符,预计需要花费 5 分钟才能阅读完成。
地位参数、关键字参数、,*
python 中函数的参数次要有地位参数和关键字参数,同时能够通过 和* 的应用来实现不定数量的地位参数、不定数量的关键字参数以及强制关键字参数传入。
地位参数
调用函数时依据函数定义的参数地位来传递参数。
def func(a,b): | |
print('a:%s,b:%s'%(a,b)) | |
>>>func(1,2)# 参数 1 是第一个参数,传给的是 a; 参数 2 是第二个参数,传给的是 b | |
a:1,b:2 | |
>>>func(2,1) | |
a:2,b:1 |
关键字参数
用于函数调用,通过“键 - 值”模式加以指定。能够让函数更加清晰、容易应用,同时也革除了参数的程序需要。在编程中倡议都应用关键字参数来传参。
def func(a,b): | |
print('a:%s,b:%s'%(a,b)) | |
>>>func(a=1,b=2) | |
a:1,b:2 | |
>>>func(b=2,a=1)# 通过键来匹配参数而不是地位 | |
a:1,b:2 |
不定数量的地位参数
通过 * 来包裹 0 个或者多个地位参数,多个地位参数被打包为一个元组传入函数中
def func1(*t): | |
print(t) | |
for i in t: | |
print(i) | |
>>>func1(1) | |
(1,) | |
1 | |
>>>func1() | |
() | |
>>>func1(1,2,3) | |
(1, 2, 3) | |
1 | |
2 | |
3 |
另一种情景是函数有固定的参数,传参时通过 * 来对参数打包:
def func(a,b): | |
print('a:%s,b:%s'%(a,b)) | |
>>>params=(10,20) | |
>>>func(*params)# 会主动将第一个参数 10 和 a 匹配;第 2 个参数 20 和 b 匹配;a:10,b:20 |
不定数量的关键字参数
通过 ** 来包裹 0 个或者多个关键字参数,多个关键字参数被打包为一个字典传入函数中
def func2(**a): | |
print(a) | |
for k,v in a.items(): | |
print(k,v) | |
>>>func2(m=1,n=2) | |
{'m': 1, 'n': 2} | |
m 1 | |
n 2 | |
>>>func2(a=1,b=2,c=3) | |
{'a': 1, 'b': 2, 'c': 3} | |
a 1 | |
b 2 | |
c 3 | |
>>>func2() | |
{} | |
另一种情景,同样的将一个字典打包传入,进入函数后会主动依据字典的 k,v 进行解析:
def func(a,b): | |
print('a:%s,b:%s'%(a,b)) | |
func(**{'a':1,'b':2})# 就相当于是 a =1,b= 1 传入。a:1,b:2 |
在理论我的项目开发中倡议都用强制关键字参数,而 ** 的打包应用,不倡议用作不定参数的传入,会让代码变得不清晰;而是下面的情景 2 的应用,对于有多个参数的函数来说,能够简化代码。
强制关键字参数
有了 * 的地位参数前面,只能跟关键字参数
def func(a,*b,c): | |
print(a,b,c) | |
>>>func(1,2,3,4,c=10) | |
1 (2, 3, 4) 10 | |
>>>func(1,2,3,4)# 前面 c 必须是关键字参数 | |
Traceback (most recent call last): | |
File "<input>", line 1, in <module> | |
TypeError: func() missing 1 required keyword-only argument: 'c' |
其实很好了解,后面有了一个不定数量的地位参数,如果最初一个不通过关键字明确指定,怎么辨认到后面不定数量的参数传完了呢?比方栗子中的 4 到底是 b 的还是 c 的,会产生歧义,因而 * 前面的参数必须跟关键字参数。
还有另一种模式:
def func1(a,*,c): | |
print(a,c) | |
>>>func1(10,c=20) | |
10 20 | |
>>>func1(10,20) | |
Traceback (most recent call last): | |
File "<input>", line 1, in <module> | |
TypeError: func1() takes 1 positional argument but 2 were given |
* 在两头不作为参数,而只是指定其前面的 c 必须通过关键字参数指定。这种用法在 scikit-learn 的源码中大量应用。这种用法的目标就是为了要让开发者在模块外部开发时都应用关键字参数传递。
另外一个点:地位参数必须在关键字参数后面,即 **args 必须在最初。
def func2(a,**b,c): | |
print(a,b,c) | |
>>>func2(1,{'t':1},c=3) | |
File "<input>", line 1 | |
def func2(a,**b,c): | |
^ | |
SyntaxError: invalid syntax | |
>>>func2(1,b=2,m=3) | |
1 2 {'m': 3} | |
>>>func2(1,b=2,m=3,k=4) | |
1 2 {'m': 3, 'k': 4} |
小结:
在开发过程中,参数的程序个别为地位参数,关键字参数;最好均应用关键字参数,能够通过 * 去限定。