Python之形参实参详解
python函数中重要的一部分就是参数的调用,今天对参数进行讲解。
参数大体上分为两种:
形参(形式参数):在定义函数阶段定义的参数称之为参数,粗略的可以认为是变量名。
实参:在调用函数阶段传入的值称之为实际参数,简称实参,粗略的可以认为是变量值。
首先清楚一下几点:
1.在调用函数阶段,实参会绑定给形参,且这种关系只能在函数体内用,结束后即被收回。
2.实参被赋予的相当于变量名的地址(后面会有解释)。
按照作用分又有以下几种:
1.位置参数:
1.1位置形参:按照从左往右的顺序依次定义的变量名,且必须被传值,多一个少一个都不行
def func(x,y):
print(x*y)
func(2,3)
1.2位置实参:按照从左往右的顺序依次定义的变量名,一一对应
def func(x,y):
print(x*y)
func(1,2)#2
func(2,1)#2
2.关键字实参:在函数调用的阶段,按照键值对的方式传入值可以完全不参照顺序,给某个形参传值。
def func(x,y):
print(x*y)
func(x=2,y=3)#6
func(y=3,x=2)#6
需要注意的是:位置形参可以和关键字实参混合使用,但必须在关键字实参之前:
错误示范:
def func(x,y):
print(x*y)
func(x=2,3)#SyntaxError: positional argument follows keyword argument
同时还应该避免向用同一个形参传值。
3.默认形参:在函数定义阶段,就已经被赋值的形参。
def func(x,y = 3):
print(x*y)
func(x = 1,y=2)#2
此时如果给默认参数赋予一个新的值,那么就会覆盖默认值。
同样位置形参可以和默认形参混用,但需要注意的是:
(1):位置形参必须在默认形参的左边(可以认为位置形参具有较高的优先级)
错误示范:
def func(x =2,y):
pass#SyntaxError: non-default argument follows default argument
需要注意到一点:默认参数的值是在函数定义阶段被赋予的,被赋予的是值的内存地址。
m=[1111,]
def func (x,y=m):
print(x,y)#1 [1111, 111]
print(type(y))#<class 'list'>
m.append(111)
func(1)
4.可变长度参数(*与**的使用)
可变长度是指在调用函数时,传入的值(实参)不固定:
实参是给形参赋值的,所以多余的实参必须要有对应的形参接收:
4.1位置参数:(*args) 输出类型为元组。
举例:
def func(x,y,*z):
print(x,y,z)
func(1,2,3,4,5)
这时候对应关系为x:1,y:2,z:(3,4,5)。
结果为:
1 2 (3, 4, 5)
<class 'tuple'>
同时也可以打印列表。
def func(x,y,*z):
print(x,y,z)
print(type(z))
func(1,2,[3,4,5])
1 2 ([3, 4, 5],)
<class 'tuple'>
实例:多个数相加:
def func(*x): #多个数相加
res = 0
for item in x:
res+=item
print(res)
func(1,2,3)#6
关键字参数:(**kwargs) 输出为字典。
举例:
def func(x,y,**kwargs):
print(x,y,kwargs)
print(type(kwargs))#字典
func(1,2,z = 3,c = 4)
1 2 {'z': 3, 'c': 4}
<class 'dict'>
补充:* 可以用在实参中,实参中带 * ,把*后面的值拆分成实参。
ex:
def func(x,y,*z):
print(x,y,z)
func(*[1,2,3,4])#1 2 (3, 4)
调用过程中把列表拆开分为1,2,3,4 再与定义阶段对应:x:1,y:2,z:(3,4)
同样的: ** 用在实参中, ** 后跟的是字典,把* * 后面的值打散成关键字实参
def func(x,y,z):
print(x,y,z)
func(**{'x':1,'y':2,'z':3})#1 2 3 把字典拆分后输出变量值
func(*{'x':1,'y':2,'z':3})#x y z 可以理解为*拆分后引用变量名
若形参和实参中都带**:
def func(x,y,**kwargs):
print(x,y,kwargs)
func(**{'x':1,'y':2,'z':3,'v':4})
1 2 {'z': 3, 'v': 4}
调用阶段字典先被拆分,使x对应1,y对应2,后面的关键字参数又被输出为字典重新打印成{‘z’: 3, ‘v’: 4}
混用* 与**:*args必须在**kwargs之前:
ex:
def func(*args,**kwargs):#考虑扩展性
print(args)
print(kwargs)
func(1,2,3,x = 1,y = 2,z = 3)
*args的作用应该是使前三个元素输出为元组,后面关键字参数输出为字典
(1, 2, 3)
{'x': 1, 'y': 2, 'z': 3}
循环调用:
def index(x,y,z):
print("=>>>>>",x,y,z)
def wrapper(a,b,c):
index(a,b,c)
print(index) #循环调用
wrapper(1,2,3)
解释:wrapper调用了1,2,3,并传给wrapper函数体内的index(a,b,c),此时打印index应该是其内存的地址,又触发index函数体
=>>>>> 1 2 3
<function index at 0x02CC7FA0>
5.命名关键字参数(了解)
在定义函数时,*后定义的参数,如下所示称之为命名关键字参数
特点:
1.必须按照key =value的形式为其传值
def func(x,y,*,a,b):#a和b称之为命名关键字参数
print(x,y)#1 2
print(a,b)#111 222
func(1,2,b = 222,a = 111)
def func(x,y,*,a=111,b ):#a和b称之为命名关键字参数 a是给命名关键字参数赋了值
print(x,y)#1 2
print(a,b)111 222
func(1,2,b =222)
6.组合使用:(了解)
形参顺序:位置形参,默认形参,*args ,命名关键字参数, **kwargs
def func(x,y = 111,*args,z,**kwargs):
print(x)
print(y)
print(args)
print(z)
print(kwargs)
实参顺序:
def func(x,y,z,a,b):
print(x)
print(y)
print(z)
print(a)
print(b)
func(1,*[1,2],**{'a':11,"b":222})
由于5和6没有实际需求场景,所以用处不太大,仅为了解。
各位读者大大,走的时候点个赞吧