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

########转自 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中的*args和**kw


学习python装饰器decorator的时候遇到*args和**kw两种函数值传递。

在python中定义函数,可以使用一般参数、默认参数、非关键字参数和关键字参数。

一般参数和默认参数在前面的学习中我们都遇到过了,而*args和**kw分别属于非关键字参数和关键字参数,后两者也都是可变参数。

非关键字参数的特征是一个星号*加上参数名,比如*number,定义后,number可以接收任意数量的参数,并将它们储存在一个tuple中。

关键字参数的特征是两个星号**加上参数名,比如**kw, 定义后,kw将接收到的任意数量参数存到一个dict中。关键字参数是在传递构成中不必按照顺序传递(因为dict内的key-value是没有顺序的),但必须要提供”传递参数名=传递参数值”形式的参数。

如:

def try_it(*args, **kw): 
    print 'args:',args 
    print 'kw:',kw 

try_it(1,2,3,4, a=1,b=2,c=3)
try_it('a', 1, None, a=1, b='2', c=3)

运行结果:

args: (1, 2, 3, 4) 
kw: {'a': 1, 'c': 3, 'b': 2} 

args: ('a', 1, None) 
kw: {'a': 1,'b': '2','c': 3, }
python中的一般参数、默认参数、非关键字参数和关键字参数可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:一般参数、默认参数、可变参数和关键字参数,先后顺序不能颠倒。即:
def func(a, b, c=0, *args, **kw):
    pass
原文地址:https://www.cnblogs.com/danniel-gong/p/12455924.html