python中函数调用定义时星号的含义(*列表,**字典)

Posted danniel-gong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python中函数调用定义时星号的含义(*列表,**字典)相关的知识,希望对你有一定的参考价值。

########转自 caixxiong:https://me.csdn.net/qq_24406903#########

 

 

调用函数时使用:*、**
    test(*args)中 * 的作用:其实就是把序列 args 中的每个元素,当作位置参数传进去。比如上面这个代码,如果 args 等于 (1,2,3) ,那么这个代码就等价于 test(1, 2, 3) 。
    test(**kwargs)中** 的作用:则是把字典 kwargs 变成关键字参数传递。比如上面这个代码,如果 kwargs 等于 {‘a‘:1,‘b‘:2,‘c‘:3} ,那这个代码就等价于 test(a=1,b=2,c=3) 。

定义函数参数时使用* 、**
def test(*args):
     这里 *args 表示把传进来的位置参数都装在元组 args 里面。比如说上面这个函数,调用 test(1, 2, 3) 的话, args 的值就是 (1, 2, 3) 。

def test(**kwargs):
    类似的, ** 就是针对关键字参数和字典的了,调用 test(a=1,b=2,c=3) 的话, kwargs 的值就是 {‘a‘:1,‘b‘:2,‘c‘:3} 了。

"普通的参数定义和传递方式和 * 们都可以和平共处,不过显然 * 必须放在所有位置参数的最后,而 ** 则必须放在所有关键字参数的最后,否则就要产生歧义了。"

上面用引号括起来的话是摘抄作者的原文,但是我做了下实验,发现在调用时,*不一定要在位置参数后面,它可以在任意位置,只要传递参数不冲突,但是**的位置则有一定要求了,因为它必须按照关键字参数的要求传递,但是关键字参数和**的位置是可以随意的.

 1 def fun(a,b,c,d,e,f,g,h,i,j):
 2     print(a,b,c,d,e,f,g,h,i,j)
 3     return
 4 L = [8,8,8,8,8]
 5 fun(1,2,3,*L,4,5)          # 1 2 3 8 8 8 8 8 4 5
 6 fun(1,2,3,*L,i=4,j=5)   # 1 2 3 8 8 8 8 8 4 5
 7 fun(1,2,3,i=4,j=5,*L)    # 1 2 3 8 8 8 8 8 4 5
 8 fun(*L,1,2,3,i=4,j=5)   # 8 8 8 8 8 1 2 3 4 5
 9 
10 D = {d:1,f:2,e:3} 
11 fun(8,8,8,**D,g=10,h=10,j=10,i=10) # 8 8 8 1 3 2 10 10 10 10
12 fun(8,8,8,g=10,h=10,j=10,i=10,**D) # 8 8 8 1 3 2 10 10 10 10

在定义函数时: *和**参数均最多有一个,**参数如果有则必须是最后一个参数,默认位置参数必须在非默认位置参数之后,而*参数则可以穿插在默认和非默认参数之间均可.

函数定义时的各类参数顺序分析
如果不考虑*参数,则参数列表只能是:(p1,p2,d1=0,d2=0,**k),其中p,d代表非默认位置参数和默认位置参数.
考虑加上参数,则有以下几种可能
(,p1,p2,d1=0,d2=0,**k),此时四个位置参数p1,p2,d1,d2必须都作为位置参数传入,当然d1,d2可以不传
(p1,*l,p2,d1=0,d2=0,**k),此时p2,d1,d2必须用位置实参传递
(p1,p2,*l,d1=0,d2=0,**k),此时d1,d2需用位置实参传递
(p1,p2,d1=0,*l,d2=0,**k),此时d2需要用位置实参传递
(p1,p2,d1=0,d2=0,*l,**k),此时位置参数按顺序给p1,p2,d1,d2,有剩余的则给l

 1 def f(*l,p1,p2,d1=0,d2=0,**k): 
 2     print(l,p1,p2,d1,d2,k) 
 3 
 4 f(1,2,3,p1=4,p2=5,d1=6,d2=7,kk=100) # (1, 2, 3) 4 5 6 7 {‘kk‘: 100}
 5 
 6 def f(p1,*l,p2,d1=0,d2=0,**k): 
 7     print(p1,l,p2,d1,d2,k) 
 8 f(1,2,3,p2=4,d1=5,d2=6,kk=100) # 1 (2, 3) 4 5 6 {‘kk‘: 100}
 9 
10 def f(p1,p2,*l,d1=0,d2=0,**k): 
11     print(p1,p2,l,d1,d2,k) 
12 f(1,2,3,4,d1=5,d2=6,kk=100) # 1 2 (3, 4) 5 6 {‘kk‘: 100}
13 
14 def f(p1,p2,d1=0,*l,d2=0,**k): 
15     print(p1,p2,d1,l,d2,k) 
16 f(1,2,3,4,5,d2=6,kk=100)  # 1 2 3 (4, 5) 6 {‘kk‘: 100}
17 f(1,d1=2,p2=3,d2=6,kk=100) # 1 3 2 () 6 {‘kk‘: 100}
18 
19 def f(p1,p2,d1=0,d2=0,*l,**k): 
20     print(p1,p2,d1,d2,l,k) 
21 f(1,2,3,4,kk=100) # 1 2 3 4 () {‘kk‘: 100}
22 f(1,2,3,4,5,kk=100) # 1 2 3 4 (5,) {‘kk‘: 100}

以上实例说明,*参数后的所有位置参数(默认和非默认)必须一关键字实参形式传递,实际上解释器也把它们定义为keyword-only参数了.

实际使用中,很少会搞这么复杂,如果硬是要所有四种参数都有,则(p,*l,d=0,**k)和(p,d=0,l,**k)这两种是最清晰的,并且这两种中第一种可能更好用,因为可以同时利用好和默认参数的特性,第二种则不能同时有两种特性.

以上是关于python中函数调用定义时星号的含义(*列表,**字典)的主要内容,如果未能解决你的问题,请参考以下文章

在函数的签名中,如果星号后面没有标识符名称,那么它在 Python 中的含义是啥? [复制]

python函数

python 函数星号参数说明

函数调用中的星号[重复]

python中星号(*)和双星号(**)的用法

函数定义中带星号的变量的默认初始化