先做个简单的用法说明:
def 函数里会传入多个实参,放到一个元组里面,以*开头,可以传多个参数;**是形参中按照关键字传值把多余的传值以字典的方式呈现
*args 表示:将实参中按照位置传值,多出来的值都给args,且以元组方式呈现
**kwargs表示:形参中按照关键字传值把多余的传值以字典方式呈现。
先说*args,上例子:
示例:
def foo(x,*args):
print(x)
print(args)
foo(1,2,3,4,5) #其中的2,3,4,5都给了args
打印结果:
1
(2, 3, 4, 5)
Process finished with exit code 0
当args与位置参数和默认参数混用的时候:特别注意三者的出场顺序
例子1 出场顺序:位置参数、默认参数、*args
def foo(x,y=1,*args):
print(x)
print(y)
print(args)
foo(1,2,3,4,5) #其中的x为1,y=1的值被2重置了,3,4,5都给了args
打印结果:
1
2
(3, 4, 5)
Process finished with exit code 0
示例2:出场顺序:位置参数,*args,默认参数
def foo(x,*args,y=1):
print(x)
print(args)
print(y)
foo(1,2,3,4,5) #其中的x为1,2,3,4,5都给了args,y按照默认参数依旧为1,注意pthon3 里面才可以这样写,python2报错
打印结果:
1
(2, 3, 4, 5)
1
Process finished with exit code 0
其中关于*,可以拆分从2个角度来看:
1.从形式参数的角度来看:
例子:
def foo(*args):#其实这一操作相当于def foo(a,b,c,d,e):
print(args)
foo(1,2,3,4,5)#其中的1,2,3,4,5都按照位置传值分别传给了a,b,c,d,e
打印结果:
(1, 2, 3, 4, 5)
Process finished with exit code 0
2.从实际参数角度来看
例子:
def foo(x,y,z):
print(x)
print(y)
print(z)
foo(*(1,2,3))#其中的*(1,2,3)拆开来看就是:foo(1,2,3),都按照位置传值分别传给了x,y,z
打印结果:
1
2
3
Process finished with exit code 0
下面进行 **kwargs的使用说明:表示就是形参中按照关键字传值把多余的传值以字典的方式呈现
例子:
def foo(x,**kwargs):
print(x)
print(kwargs)
foo(1,y=1,a=2,b=3,c=4)#将y=1,a=2,b=3,c=4以字典的方式给了kwargs
打印结果:
1
{'y': 1, 'a': 2, 'b': 3, 'c': 4}
Process finished with exit code 0
关于**kwargs与位置参数、*args、默认参数混着用的问题:(注意出场顺序)
位置参数、*args、**kwargs三者的顺序必须是位置参数、*args、**kwargs,不然就会报错:
例子:
def foo(x,*args,**kwargs):
print(x)
print(args)
print(kwargs)
foo(1,2,3,4,y=1,a=2,b=3,c=4)#将1传给了x,将2,3,4以元组方式传给了args,y=1,a=2,b=3,c=4以字典的方式给了kwargs
打印结果:
1
(2, 3, 4)
{'y': 1, 'a': 2, 'b': 3, 'c': 4}
Process finished with exit code 0
出场顺序错误,示例示范:
def foo(x,**kwargs,*args):
print(x)
print(args)
print(kwargs)
foo(1,y=1,a=2,b=3,c=4,2,3,4)
打印结果报错:
File "E:/PythonDemo/DoMore/can.py", line 1
def foo(x,**kwargs,*args):
^
SyntaxError: invalid syntax
Process finished with exit code 1
强调:
位置参数、默认参数、**kwargs三者的顺序必须是位置参数、默认参数、**kwargs,不然就会报错:
def foo(x,y=1,**kwargs):
print(x)
print(y)
print(kwargs)
foo(1,a=2,b=3,c=4)#将1按照位置传值给x,y按照默认参数为1,a=2,b=3,c=4以字典的方式给了kwargs
打印结果:
1
1
{'a': 2, 'b': 3, 'c': 4}
Process finished with exit code 0
那么接下来,关于 **,可以从2个角度拆分来看:
1.从形参的角度拆分来看:
例子:
def foo(**kwargs):#其实就是相当于def foo(y,a,b,c)
print(kwargs)
foo(y=1,a=2,b=3,c=4)
打印结果:
{'y': 1, 'a': 2, 'b': 3, 'c': 4}
Process finished with exit code 0
2.从实参的角度来看
例子一:
def foo(a,b,c,d):
print(a)
print(b)
print(c)
print(d)
foo(**{"a":2,"b":3,"c":4,"d":5})#**{"a":2,"b":3,"c":4,"d":5}是将字典里的每个值按照关键字传值的方式传给a,b,c,d
打印结果:
2
3
4
5
Process finished with exit code 0
例子二:
def foo(a,b,c,d=1):
print(a)
print(b)
print(c)
print(d)
foo(**{"a":2,"b":3,"c":4})#**{"a":2,"b":3,"c":4}是将字典里的每个值按照关键字传值的方式传给a,b,c;d依旧按照默认参数
打印结果:
2
3
4
1
Process finished with exit code 0