一、函数形参前的星号

函数形参前有星号表明是不定传参,但有以下区别:

1.一个星号

形参前有一个星号表明将接受到的参数用元组的形式保存起来,示例如下:

def test(*args):

    print args

test(1, 2, 3, 4)

输出为:

(1, 2, 3, 4)

注意,调用此类函数时传参不可以带有参数名,否则会抛出unexpected keyword argument”异常。

 

2.两个星号

同上,也是不定传参,但上一个例子不可以传递参数名,而两个星号正是解决这种问题的,它将接受到的参数用字典的形式保存起来,示例如下:

def test(**kwargs):

    print kwargs

test(a=1, b=2, c=3, d=4)

输出为:

{'a': 1, 'c': 3, 'b': 2, 'd': 4}

这样在函数内部可以通过参数名读出所需的参数。

 

二、函数调用中传参前的星号

上一部分是介绍了将不定参数打包为某个数据类型,但在传参中也可以将相应的数据类型解包后传递。

1.一个星号

表明将元组类型的数据解包后,依次传递给调用的函数,示例:

def test(a, b, c):

    print a + b + c

args = (1, 2, 3)

test(*args)

输出为:

6

 

2.两个星号

表明将字典类型的数据解包后,按照参数名,传递给函数调用中对应的形参,示例:

def test(a, b, c):

    print a

    print b

    print c

kwargs = {"b" : 1, "a" : 2, "c" : 4}

test(**kwargs)

输出为:

2

1

4

 

三、参数对应的问题

那么,在我们传参用星号解包时,必须要一一对应所有形参吗,先看一个示例:

def test(a, b, c):

    print a

    print b

    print c

kwargs = {"b" : 1, "a" : 2, "c" : 4, "d" : 5, "e" : 6}

test(**kwargs)

输出为:

TypeError: test() got an unexpected keyword argument

 

可以看到,解包时不能和形参的名称或者数量高于。但非要这样也有办法,就是再用不定传参,示例:

def test(a, b, c, **kwargs):

    print a

    print b

    print c

    print kwargs

kwargs = {"b" : 1, "a" : 2, "c" : 4, "d" : 5, "e" : 6}

test(**kwargs)

输出为:

2

1

4

{'e': 6, 'd': 5}

 

可以看到,程序先匹配了能找到的参数,找不到的参数统统又重新打包给了形参kwargs。两个星号是这样,单个星号也一样,唯一的却别是,两个星号可以通过参数名将所需的参数拿走后其余的全部打包,而一个星号只能按照顺序一一对应传参,超出的部分再全部打包为元组。