位置参数、关键字参数、*

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}

小结:

在开发过程中,参数的顺序一般为位置参数,关键字参数;最好均使用关键字参数,可以通过*去限定。


千翻娃儿
4 声望6 粉丝