介绍
编程时,您可能并不知道代码的所有可能的用途,并且可能希望为将来使用该模块的程序员或者为用户与代码交互提供更多选择。我们可以通过在我们的代码中使用*args
和**kwargs将可变数量的参数传递给函数。
理解 *args (可变参数)
在Python中,*args
可以使用单星号形式作为参数将非密钥变长变量列表发送到函数。值得注意的是,星号(*
)是这里的重要元素,因为这个词args
是既定的常规习惯用法,尽管它不是由该语言强制执行的。
让我们看看使用两个参数的典型函数:
def multiply(x, y):
print (x * y)
在上面的代码中,我们使用x和y作为参数构建函数,然后当我们调用函数时,我们需要使用数字来与x和对应y。在这种情况下,我们将5传递给x ,4传递给y:
def multiply(x, y):
print (x * y)
multiply(5, 4)
现在,我们可以运行上面的代码,我们将收到以下输出,显示整数5和4按照multiply(x,y)
函数相乘:
Output:
20
如果稍后我们决定将三个数字而不是两个数字相乘?如果我们尝试为该函数添加一个附加数字,如下所示,我们将收到一个错误。
def multiply(x, y):
print (x * y)
multiply(5, 4, 3)
Output
TypeError: multiply() takes 2 positional arguments but 3 were given
因此,如果您怀疑以后可能需要使用更多参数,则可以*args
改为将其用作参数。
我们基本上可以创建与第一个示例中显示的功能和代码相同的功能和代码,方法是删除x
并y
作为函数参数,然后替换为*args
:
def multiply(*args):
z = 1
for num in args:
z *= num
print(z)
multiply(4, 5)
multiply(10, 9)
multiply(2, 3, 4)
multiply(3, 5, 10, 6)
当我们运行这个代码时,我们会收到这些函数调用的产品:
Output:
20
90
24
900
因为我们用来*args
发送一个可变长度的参数列表给我们的函数,所以我们能够传入尽可能多的参数,就像我们希望进入函数调用一样。
随着*args
你可以创建一个接受你的函数中的非keyworded参数变化量更灵活的代码。
理解 **kwargs(关键字参数)
双星号形式**kwargs
用于将keyworded,可变长度参数字典传递给函数。同样,这两个星号(**
)在这里是重要的元素,因为这个词kwargs
通常被使用,尽管没有被语言强制执行。
就像*args
,**kwargs
可以采取任何你想提供给它的论据。但是,**kwargs
不同之处*args
在于您需要分配关键字。
首先,我们只需打印出**kwargs
传递给函数的参数。我们将创建一个简短的函数来执行此操作:
print_kwargs.py
def print_kwargs(**kwargs):
print(kwargs)
接下来,我们将调用带有一些传入函数的keyworded参数的函数:
def print_kwargs(**kwargs):
print(kwargs)
print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)
让我们运行上面的程序,看看输出:
Output:
{'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'}
根据您当前使用的Python 3的版本,字典数据类型可能无序。在Python 3.6及更高版本中,您将按顺序收到键值对,但在早期版本中,这些对将以随机顺序输出。
重要的是要注意的是,**kwargs
创建了一个名为字典的字典,我们可以像处理其他字典一样使用它。
让我们创建另一个简短的程序来展示我们如何使用**kwargs
。在这里,我们将创建一个函数来迎接名称字典。首先,我们将从两个名字的字典开始:
def print_values(**kwargs):
for key, value in kwargs.items():
print("The value of {} is {}".format(key, value))
print_values(my_name="Sammy", your_name="Casey")
我们现在可以运行该程序并查看输出:
Output:
The value of your_name is Casey
The value of my_name is Sammy
同样,因为字典可能是无序的,所以你的输出可能首先带有名字,Casey或者带有名字Sammy。
让我们现在传递更多的参数给该函数,以表明**kwargs它将接受您希望包含的许多参数:
def print_values(**kwargs):
for key, value in kwargs.items():
print("The value of {} is {}".format(key, value))
print_values(
name_1="Alex",
name_2="Gray",
name_3="Harper",
name_4="Phoenix",
name_5="Remy",
name_6="Val"
)
当我们在这个时候运行这个程序时,我们会收到下面的输出,这个输出可能又是无序的:
Output:
The value of name_2 is Gray
The value of name_6 is Val
The value of name_4 is Phoenix
The value of name_5 is Remy
The value of name_3 is Harper
The value of name_1 is Alex
使用 **kwargs 使我们能够灵活地在我们的程序中使用关键字参数。当我们 **kwargs 用作参数时,我们不需要知道我们最终想要传递给函数的多少个参数。
参数排序
在函数或函数调用中对参数进行排序时,参数需要按特定顺序排列:
- 正式的位置参数
- *args
- 关键字参数
- **kwargs
实际上,当使用显式位置参数 *args 和 **kwargs 时,你的函数看起来像这样:
def example(arg_1, arg_2, *args, **kwargs):
...
而且,除了*args
和以外,当使用位置参数以及关键字参数时 **kwargs,您的函数将如下所示:
def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs):
...
在创建函数时,记住参数的顺序非常重要,以便在Python代码中不会收到语法错误。
在函数调用中使用 *args 和 **kwargs
我们也可以使用 *args 和 **kwargs 将参数传递给函数。
首先,我们来看一个使用*args的例子。
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,arg_2 和 arg_3 。该函数将输出每个参数。然后我们创建一个为可迭代的集合变量(在本例中为一个元组),并且可以使用星号语法将该变量传递给该函数。
当我们运行 some_args 程序命令时,我们会收到以下输出:
Output:
arg_1: Sammy
arg_2: Casey
arg_3: Alex
我们也可以将上面的程序修改为具有不同变量名称的可迭代列表数据。我们还将*args
语法与命名的参数结合起来:
def some_args(arg_1, arg_2, arg_3):
print("arg_1:", arg_1)
print("arg_2:", arg_2)
print("arg_3:", arg_3)
my_list = [2, 3]
some_args(1, *my_list)
如果我们运行上面的程序,它将产生以下输出结果:
Output:
arg_1: 1
arg_2: 2
arg_3: 3
同样,**kwargs(关键字参数)也可以用来调用一个函数。我们将设置一个变量,它等于一个带有3个键值对的字典(这里使用 kwargs,但在任何时候都可以调用它),然后将它传递给带有3个参数的函数:
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)
让我们用以下python some_kwargs.py
命令运行上面的程序:
Output:
kwarg_1: Val
kwarg_2: Harper
kwarg_3: Remy
在调用函数时,可以使用*args
和**kwargs
传递参数。
结论
我们可以使用函数定义中的特殊语法*args和**kwargs来传递可变数量的参数给函数。
创建包含*args和**kwargs的函数,最好使用在你期望参数列表中的输入数量保持相对较小的时候。使用的*args和**kwargs主要是提供可读性和便利,但应谨慎使用。