一、可变长度的参数(*与**的用法)
可变长度指的是在调用函数时,传入的值(实参)的个数不固定
而实参是用来为形参赋值的,所以对应着。针对溢出的实参必须有对应的形参来接收
1.可变长度的位置参数
形参格式:*形参名 用来接收溢出的位置参数,溢出的位置参数会被*保存成元祖的格式然后赋值紧跟其后的形参名
*后跟的可以是任意名字,但是约定俗成应该是args
def func(x,y,*z): #*用来接收溢出的位置参数(3,4,5),然后赋值给紧跟其后的形参名z=(3,4,5)
print(x,y,z)
func(1,2,3,4,5)
# 1 2 (3, 4, 5)
求多个数的和,并返回结果
def func1(*args):
sum=0
for i in args:
sum+=i
#return sum 如果return写for循环里面,for循环一次相加就被return结束了
return sum
res=func1(1,2,3,4,5)
print(res)
# 15
2.可变长度的关键字参数
形参格式:**形参名 用来接收溢出的关键字参数,溢出的关键字参数会被**保存成字典的格式然后赋值紧跟其后的形参名
**后跟的可以是任意名字,但是约定俗成应该是kwargs
def func(x,y,**kwargs):
print(x,y,kwargs)
func(1,y=2,a=1,b="c",d=5)
# 1 2 {'a': 1, 'b': 'c', 'd': 5}
3.*可以用在实参中,实参中带*,先将*后的值打散成位置实参
def func(x,y,z):
print(x,y,z)
#func([11,22,33]) 这种会报错,传入的实参[11,22,33]是一个位置实参
func(*[11,22,33]) #实参中带*,先将*后的值打散成位置实参(相当于for循环列表)即func(11,22,33)
# 11 22 33
li=[11,22,33]
func(*li)
# 11 22 33
4.实参与形参中都带*
def func(x,y,*args): #*用来接收溢出的位置参数([11,33,55],),然后赋值给紧跟其后的形参名args=([11,33,55],)
#*用来接收溢出的位置参数(22,44,66)然后赋值给紧跟其后的形参名args=(22,44,66)
print(x,y,args)
func(1,2,3,4,5,6,7)
#1 2 (3, 4, 5, 6, 7)
func(1,2,[11,33,55]) #实参中[11,33,55]是溢出的位置实参会被形参中的*接收
#1 2 ([11, 33, 55],)
func(1,2,*[22,44,66]) #实参中带*,先将*后的值打散成位置实参(相当于for循环列表)即func(1,2,22,44,66)
#1 2 (22,44,66)
5.**可以用在实参中(**后跟的只能是字典),实参中带**,先将**后的值打散成关键字实参
def func(x,y,z):
print(x,y,z)
func(*{'x':1,'y':2,'z':3})#实参中带*,先将*后的值打散成位置实参(相当于for循环字典)即func(x,y,z)
# x y z
func(**{'x':1,'y':2,'z':3})#实参中带**,先将**后的值打散成关键字实参即func(x=1,y=2,z=3)
# 1 2 3
错误的传参
func(**{'x':1,'y':2}) #实参中带**,先将**后的值打散成关键字实参即func(x=1,y=2)实参传参没有z,形参有参数z,所以实参与形参参数不对应
func(**{'x':1,'a':2,'z':3}) #实参中带**,先将**后的值打散成关键字实参即func(x=1,a=2,z=3)实参传参传入a,形参没有参数a,所以实参传参与形参参数不对应
6.形参与实参中都带**
def func(x,y,**kwargs): #**用来接收溢出的关键字参数,溢出的关键字参数会被**接收,保存成字典的格式{'a':33,'c':44}然后赋值紧跟其后的形参名kwargs={'a':33,'c':44}
print(x,y,kwargs)
func(**{'y':22,'x':11,'a':33,'c':44})#实参中带**,先将**后的值打散成关键字实参func(y=22,x=11,a=33,c=44)
#11 22 {'a': 33, 'c': 44}
7.混用*与**
*args必须在**kwargs之前
def func(*args,**kwargs):#*用来接收溢出的位置参数(1,2,3,4,5),然后赋值给紧跟其后的形参名args=(1,2,3,4,5)
#**用来接收溢出的关键字参数,溢出的关键字参数会被**接收,保存成字典的格式{'a':11,'b':22,'c':33}然后赋值紧跟其后的形参名kwargs={'a':11,'b':22,'c':33}
print(args,kwargs)
func(1,2,3,4,5,a=11,b=22,c=33) #实参中1,2,3,4,5是溢出的位置实参会被形参中的*接收,实参中{'a': 11, 'b': 22, 'c': 33}是溢出的关键字实参会被形参中的**接收
#(1, 2, 3, 4, 5) {'a': 11, 'b': 22, 'c': 33}
def index(x,y,z):
print('index-->',x,y,z) #index--> 1 2 3
def other(a,b,c): #a=1,b=2,c=3
index(a,b,c) #2.index函数所使用的位置实参值,是other函数位置形参所提供的。 即index(1,2,3)
other(1,2,3) #1.为other函数传递的参数是给index函数参数使用的
#为other函数传递的参数要遵循index函数的参数规则
针对上面的优化
def index(x,y,z):
print('index-->',x,y,z) #index--> 1 2 3
def other(*args,**kwargs): #args=(1,) kwargs={'z:'2,'y':3}
index(*args,**kwargs) #即index(*(1,),**{'z':2,'y':3})
other(1,z=2,y=3) #为other函数传递的参数是给index函数参数使用的
#为other函数传递的参数要遵循index函数的参数规则
#第一步:调用other函数,1是溢出的位置实参会被other函数中*接收,保存成元祖格式,然后赋值给紧跟其后的形参名args=(1,)
#z=2,y=3是溢出的关键字实参会被other函数中**接收,保存成字典格式,然后赋值给紧跟其后的形参名kwargs={'z':2,'Y':3}
#即 index(*(1,),**{'z:'2,'y':3})
#第二步:调用index函数,函数中实参中出现*先将*后的值打散成位置实参(相当于for元祖) index(1,)
#函数中出现**先将**后的值打散成关键字实参 index(z=2,y=3)
#即index(1,z=2,y=3) 为other函数传递的参数要遵循index函数的参数规则