在阅读前人圣贤的代码时,不知大家是否注意到有两个比较奇怪的参数传入函数,一个是*args,另外一个是**kwargs,其实大家不要不他俩想得很高深,这两个参数主要是用于函数中处理可变数量参数的特殊语法。【最主要的其实是*和**的作用,args和kwargs只是大家约定俗成的一个名字】
首先我们需要明白两个基础概念:【位置参数】【关键字参数】
【位置参数】:参数的位置顺序决定了它们的值被传递到函数的哪个参数。在函数定义中,位置参数是按照顺序声明的,调用时你需要按照相同的顺序传递值。举个例子
def fun(arg1,arg2): pass fun(1,2)在调用函数fun时,传入参数的顺序决定把谁传递给谁,在本例中就是把1对应于arg1传入函数,2对应于arg2传入函数,与位置有关
【关键字参数】:可以通过参数名指定传递的值,而不必按照位置顺序。再举个例子:
def fun(arg1,arg2): pass fun(arg2=1,arg1=2)即在函数调用的时候,指明每个参数等于什么,这样就可以不用记住每个参数的位置,可以增加程序的可读性,与位置无关
了解了位置参数与关键字参数,现在我们来学习*args与**kwargs两个参数,其实真正起作用的是*和**:
*args
*的作用(*args):在不同的地方有不同的作用
- 【定义函数】:打包--将多个参数打包成一个元组
- 【调用函数】或者【出现在函数体内部】:解包--将一个元组解包成多个参数
举例说明:在【定义函数】时:
def fun(*args): print(args) fun(1,2,3) >>>(1,2,3) fun(1,2,3,4,'a','abc') >>>(1,2,3,4,'a','abc')*的作用是把所有传进去的【位置参数】都打包成了一个元组
在【调用函数】或者【出现在函数体内部】时:
#调用函数 def fun(a,b,c): print(a,b,c) args=(1,2,3) fun(*args) >>>1 2 3 #实现了解包操作 '''如果是args=(1,2,3,4),那么解出来有四个值,但是原本定义的函数fun只有三个参数,此时调用fun(*args)就会报错''' #出现在函数体内部 def fun(a,b,c): print(args) print(*args) args=(1,2,3) #相当于全局变量 fun(0,0,0) #随便传入3个值 >>>(1,2,3) #print(args) >>>1 2 3 #print(*args)--实现了解包操作在这里*的作用就是将args进行解包
**kwargs
学习完了*args的作用,可以大概估计一下**kwargs的作用,其实就是对【关键字参数】进行打包与解包
与*args一样,**kwargs在不同的地方也有不同的作用
- 在函数定义时:对关键字参数进行打包成字典形式
- 在函数调用时:对字典进行解包成关键字参数形式
举例说明:
#定义函数 def fun(**kwargs): print(kwargs) fun(a=1,b=2) >>>{'a':1,'b'=2} #调用函数 def fun(a,b) print(a,b) kwargs={'a=1','b'=2} fun(**kwargs) >>>1 2
一般来说很多时候我们经常看到这两个参数经常放到一起使用:
#定义函数 def fun(*args,**kwargs): print(args) print(*args) print(kwargs) a=(1,2,3) b=[4,5,6] fun(a,b,c=7,d=8) >>>((1,2,3),[4,5,6]) >>>(1,2,3) [4,5,6] >>>{'c':7,'d':8} #有一点需要注意的是,关键字参数必须位于位置参数之后,否则会报错 #例如在本例中,fun(a,c=7,b,d=8)的写法是错误的
总结:
- *的作用就是将【位置参数】打包成元组放到args中,或者将args解包成【位置参数】
- **的作用是将【关键字参数】打包成字典放到kwargs中,或者将kwargs解包成【关键字参数】