Python中*args和**kwargs用法

用法

Python的参数有位置参数和关键字参数之分.位置参数之间有顺序之分.在函数定义或者函数调用时,各种参数之间的顺序是有要求的: 1.Formal positional arguments;2.*args;3.Keyword arguments;4.**kwargs

区分 本质 特点 函数定义 函数调用
*args tuple元组 不定长[主要针对函数定义],内部元素有序 作为形参,需要在函数体中对args元素进行逐个解析; 当调用*args为形参的函数时,传递参数可以不定长[若干位置参数被打包成一个tuple(个人理解)] 函数在定义时,已经定义了若干形参,通过*args来进行调用时,会对args进行解包,内部元素会按照顺序依次给函数的形参进行赋值
**kwargs dict字典 不定长[主要针对函数定义],内部元素无序 作为形参,需要在函数体内对kwargs元素进行逐个解析,不过可以通过key获取相应的value值; 当调用**kwargs为形参的函数时,传递的关键字参数可以不定长[若干关键字参数被打包成一个dict字典,然后传递(个人理解)] 函数定义时,已经定义了若干关键字参数;通过**kwargs进行调用时,会先对kwargs字典进行解包,通过函数形参对kwargs字典进行查找并取值

函数定义

*args

1
2
3
4
5
6
7
8
9
10
11
def multiply(*args):
z = 1
for num in args:
z *= num
print(z)

# 可以看到参数不定长
multiply(4, 5) # 20
multiply(10, 9) # 90
multiply(2, 3, 4) # 24
multiply(3, 5, 10, 6) # 900

**kwargs

1
2
3
4
5
def print_kwargs(**kwargs):
print(kwargs)

print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)
# {'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'} # 可以看出理解应该没问题,被打包成一个dict,然后传递

函数调用

函数调用时, 被传递的参数无论是*args或者**kwargs,在函数执行时,传递的参数需要解包,然后把解包元素依次赋值给函数定义时的相应形参(在函数定义时,形式参数可能是确定的,也就是说是定长的). 如果再用不定长进行调用,容易出错[例外的是,关键字参数,如果相应关键字参数有默认值,那么不定长还生效]

注意,如果kwargs以一个星号*解析,那么只会解包出kwargs的key.

*args

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def some_args(arg_1, arg_2, arg_3):
print("arg_1:", arg_1)
print("arg_2:", arg_2)
print("arg_3:", arg_3)

args = ("Sammy", "Casey", "Alex")
some_args(*args)

# arg_1: Sammy
# arg_2: Casey
# arg_3: Alex

args1 = ("Sammy", "Alex")
some_args(*args1)
# TypeError: some_args() missing 1 required positional argument: 'arg3'

# 换一种调用方式,补全了参数个数
some_args("Casey", *args1)
# 运行正常
# arg_1: Casey
# arg_2: Sammy
# arg_3: Alex

**kwargs

kwargs关键字的key必须和函数定义时,形式参数的名称一模一样, 否则调用时会报错,TypeError.

kwargs字典被解包[],然后根据函数定义时,形式参数的名称,在kwargs字典中查找,

  • 没找到,报错 TypeError: some_function() got an unexpected keyword argument 'arg3'
  • 找到了,设置为相应的值,运行函数体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def some_kwargs(kwarg_1, kwarg_2, kwarg_3):
print("kwarg_1:", kwarg_1)
print("kwarg_2:", kwarg_2)
print("kwarg_3:", kwarg_3)

kwargs = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_3": "Remy"}
some_kwargs(**kwargs)
# kwarg_1: Val
# kwarg_2: Harper
# kwarg_3: Remy

# 字典key和函数定义时的形式参数名称不一致
kwargs1 = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_4": "Remy"}
some_kwargs(**kwargs1)
# TypeError: some_args() got an unexpected keyword argument 'kwarg_4'

# 字典的参数内容少了

kwargs1 = {"kwarg_1": "Val", "kwarg_2": "Harper"}
some_kwargs(**kwargs2)
#TypeError: some_args() missing 1 required positional argument: 'kwarg_3'

References

https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3

您的支持就是我更新的最大动力!谢谢!