函数的参数可以分为:
形式参数(形参):在函数定义阶段,括号内定义的参数/变量名成为形参
实际参数(实参):在函数调用阶段,括号内传入的值/变量值称为实参
ps:在调用函数阶段会将实参(值)绑定给形参(变量名),这种绑定关系只在调用函数时生效,在函数执行完毕就会解除这种绑定关系。
二、细分:
1.位置形参
1.1位置形参:再定义阶段,按照从左到右的顺序依次定义的形参称之为位置形参
特点:但凡按照位置定义的形参,必须被传值,多一个或少一个都不行。
def func(x,y,z): print(x,y,z) # func(1,2)#报错 func(1,2,3) # func(1,2,3,4)#报错
1.2位置实参:在调用阶段,按照从左到右的顺序依次传入的值称之为位置实参
特点:
1.必须形参一一对应
def func(x,y,z): print(x,y,z) func(2,1,3) #2 1 3
2.关键字实参:在调用函数阶段,按照key = values的形式的实参称之为关键字参数。
特点:可以打乱顺序,但依然能为指定的形参传值(总结,根据形参/变量名传值)
def func(x,y,z): print(x,y,z) func(x=1,y=2,z=3)#关键字传值 func(1,2,3)#位置实参 func(z=3,y=2,x=1)#关键字实参顺序无关
实参的形式是位置实参与关键字实参混合使用,但是必须准守以下规则
1.位置实参必须在关键字参数之前
2.不能为同一个值反复传值
func(1,z=3,y=2) func(z=3,1,y=2) #错误 func(1,z=3,x=2,y=3) #错误
默认形参:定义阶段,就已经为形参赋值,该参数称之为默认形参
特点:
1.定义阶段就已经有值意味着调用阶段可以不用传值。
2.位置形参必须放在默认默认参数前面
3.默认参数的值在函数定义阶段就已经固定死了,定义阶段之后的改动不会影响该值
4.默认形参的值通常应该是不可变类型。
def func(x,y,z=100): print(x,y,z) func(10,20)#不需要对z传值 func(10,20,200)#也可以对z传值
默认形参主要主要对于多次传入实参相同的函数而定义。
def register(name,age,sex='male'): print(name,age,sex) register('egon',18,) register('lxx',38,) register('cw',48,) register('yyh',58,) register('alex',73,'female')
def func(x,z=100,y): print(x,y,z)#报错,位置形参必须在默认参数前面
m=10 def func(x,y,z=m): #z=10 print(x,y,z) m=100 func(1,2) #函数定义完成后的,修改默认参数,对函数没有修改作用 #1 2 10
4.可变长参数
可变长实参:指的是在调用的阶段,实参数的个数是不固定的
实参无非两种形式(位置,关键字实参),对应形参也必须有两种解决方法来分别接受溢出的位置参数或关键字实参
*----》溢出的位置参数
**-----》溢出的关键字参数
def sum2(*x): #x=(1,2,3,4,5) res=0 for i in x: res+=i return res print(sum2(1,2,3,4,5)) #15
4.1 *的用法
在形参前面加*,*会将溢出的位置实参存成元组形式,然后赋值给*后形参/变量名
def func(x,y,*z): #z=(3,4,5) print(x,y,z) func(1,2,3,4,5) #1 2 (3,4,5)
在实参前加*:但凡碰到实参中带*的,先将实参打散成位置实参再与形参做对应
def func(x,y,z): print(x,y,z) func(1,2,[3,4,5]) #func(*[1,2,3,4,5]) #func(1,2,3,4,5)报错 func(*[1,2,3]) #func(1,2,3) #1 2 [3,4,5] #1 2 3
def func(x,y,*z): print(x,y,z) func(1111,2222,*[1,2,3,4,5]) #func(1111,2222,1,2,3,4,5) #1111 2222 (1,2,3,4,5)
4.2 **的用法
在形参前加**:**会将溢出的关键字实参存成字典的形式,然后赋值给**后的形参名
def func(x,y,**z): #z={'c':3,'b':2,'a':1} print(x,y,z) func(1,y=2,a=1,b=2,c=3) #1 2 {'a': 1, 'b': 2, 'c': 3}
在实参前加**:但凡碰到实参中带**的,先将实参打散成关键字实参再与形参做对应
def func(x,y,z): print(x,y,z) func(1,**{'y':2,'z':3}) #func(1,z=3,y=2) #func(1,**{'a':2,'y':333,'z':3}) #func(1,a=2,y=333,z=3) # 错误 #1 2 3
形参中:*args,**kwargs,表示接受溢出的位置实参,溢出的关键字实参(编程中常用的定义方式)
def func(x,*args): print(x) print(args) def func(x,**kwargs): print(x) print(kwargs)
*与**的应用:
def index(name,age,sex): print('index=====>',name,age,sex) def wrapper(*args,**kwargs): #args=('egon',) kwargs={'sex':'male','age':18} # print(args) # print(kwargs) index(*args,**kwargs) #index(*('egon',),**{'sex':'male','age':18}) #index('egon',sex='male',age=18) # wrapper(1,2,3,4,5,a=1,b=2,c=3)#取决index函数所需的形参并不是所有参数都可以传入。 wrapper('egon',sex='male',age=18) #index=====> egon 18 male