Vinn's Studio

Python Syntax: *args and **kwargs

Word count: 983Reading time: 3 min
2021/07/29 Share

Python 中不定长参数的一些使用方法。

在定义函数时传入的形式参数中,有些是函数运行所必需的参数,在函数被调用时,这些参数必须以正确的顺序传入,传入的数量必须和声明时的一样,不然会出现语法错误。这些必须以正确形式传入的参数称为必备参数

同时,有些形式参数并不是函数运行所必需的,输入这些参数能够对函数的输出结果造成一定影响,但是没有它们也不影响函数的正常运行。开发者在定义函数时也不能确定这类参数的具体数量,这些参数就是可变参数

形式参数 *args**kwargs 被称为不定长参数,在定义函数时用来处理可变参数。注意:args 和 kwargs 可以修改为其它变量名,重要的其实只是星号。

args 是 arguments 的缩写,表示位置参数;kwargs 是 keyword arguments 的缩写,表示关键字参数。这其实就是 Python 中可变参数的两种形式,*args 表示所有的位置参数,**kwargs 表示所有的关键字参数,并且 *args 必须放在 **kwargs 的前面(因为位置参数在关键字参数的前面)。

  • 位置参数允许你传入 0 个或任意个参数,这些位置参数在函数调用时自动组装为一个tuple
  • 关键字参数允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

实参与形参

  • 形式参数:形参出现在函数定义中,在整个函数体内都可以使用, 离开该函数则不能使用;

  • 实际参数:实参出现在主调函数中,进入被调函数后,实参变量也不能使用;

*args 的用法

在定义函数时,*args元组(tuple)的形式传递一个可变参数列表给函数,这个参数列表的长度未知,甚至长度可以为 0:

1
2
3
4
5
6
7
def test_args(first, *args):
print('Required argument: ', first)
print(type(args))
for v in args:
print ('Optional argument: ', v)

test_args(1, 2, 3, 4)

第一个形式参数 first 是必须要传入的参数,而后面三个形式参数以可变参数列表的形式传入函数,并且是作为元组 tuple 来使用的。代码的运行结果如下:

1
2
3
4
5
Required argument:  1
<class 'tuple'>
Optional argument: 2
Optional argument: 3
Optional argument: 4

**kwargs 的用法

在定义函数时,**kwargs 是以字典(dict)的形式,将一个可变的参数名-参数值字典传给函数,同样,该字典的长度可以为 0 或为其他值:

1
2
3
4
5
6
7
8
9
def test_kwargs(first, *args, **kwargs):
print('Required argument: ', first)
print(type(kwargs))
for v in args:
print ('Optional argument (args): ', v)
for k, v in kwargs.items():
print ('Optional argument %s (kwargs): %s' % (k, v))

test_kwargs(1, 2, 3, 4, k1=5, k2=6)

代码的运行结果如下:

1
2
3
4
5
6
7
Required argument:  1
<class 'dict'>
Optional argument (args): 2
Optional argument (args): 3
Optional argument (args): 4
Optional argument k2 (kwargs): 6
Optional argument k1 (kwargs): 5

调用函数

*args**kwargs 不仅可以在函数定义中使用,还可以在函数调用中使用。在调用时使用它们,就相当于对实际参数进行 pack(打包)和 unpack(解包)。

对于 *args

1
2
3
4
5
6
7
def test_args_kwargs(arg1, arg2, arg3):
print("arg1:", arg1)
print("arg2:", arg2)
print("arg3:", arg3)

args = ("two", 3, 5) # 将实际参数打包为 tuple
test_args_kwargs(*args) # 传入函数中解包

输出结果为:

1
2
3
arg1: two
arg2: 3
arg3: 5

对于 **kwargs

1
2
kwargs = {"arg3": 3, "arg2": "two", "arg1": 5} # 将实际参数打包为 dict
test_args_kwargs(**kwargs) # 传入函数中解包

输出结果为:

1
2
3
arg1: 5
arg2: two
arg3: 3

args和kwargs组合起来可以传入任意的参数,这在参数未知的情况下是很有效的,同时加强了函数的可拓展性。

CATALOG
  1. 实参与形参
  2. *args 的用法
  3. **kwargs 的用法
  4. 调用函数