如何在 Python 3 中使用 *args 和 **kwargs

介绍

函数定义, 参数中,指定一个函数可以接受的参数的实体被命名。

在编程时,您可能不知道您的代码的所有可能的用例,并且可能希望为未来的程序员提供更多选项,以便他们使用该模块,或者为与代码互动的用户提供更多选项。

前提条件

如果您没有设置编程环境,您可以参考本地编程环境的安装和安装指南(https://www.digitalocean.com/community/tutorial_series/how-to-install-and-set-up-a-local-programming-environment-for-python-3)或适用于您的操作系统(Ubuntu, CentOS, Debian 等)的编程环境(https://www.digitalocean.com/community/tutorial_collections/how-to-install-python-3-and-set-up-a-programming-environment)。

了解 *args

在Python中,单星形args可以用作参数,将一个非关键字变长参数列表发送到函数中,值得注意的是,星座(*)是这里的重要元素,因为args这个词是既定的常规词语,尽管它不是语言所强加的。

<$>[info] 信息: 要跟进本教程中的示例代码,请在本地系统上运行python3命令,打开Python交互壳。

让我们来看看一个使用两个参数的典型函数:

1[label lets_multiply.py]
2def multiply(x, y):
3    print (x * y)

在上面的代码中,我们用xy作为参数构建了函数,然后当我们调用函数时,我们需要使用数字来匹配xy

1[label lets_multiply.py]
2def multiply(x, y):
3    print (x * y)
4
5multiply(5, 4)

现在,我们可以运行上面的代码:

1python lets_multiply.py

我们将获得以下输出,表明整数5和4被按倍增(x,y)函数倍增:

1[secondary_label Output]
220

如果稍后我们决定要将三个数字倍增,而不是仅仅两个?如果我们尝试将一个额外的数字添加到函数中,如下所示,我们会收到错误。

1[label lets_multiply.py]
2def multiply(x, y):
3    print (x * y)
4
5multiply(5, 4, 3)
1[secondary_label Output]
2TypeError: multiply() takes 2 positional arguments but 3 were given

因此,如果您怀疑您可能需要稍后使用更多参数,您可以使用*args作为参数。

基本上,我们可以创建我们在第一例中所示的相同的函数和代码,删除xy作为函数参数,并用*args代替它们:

 1[label lets_multiply.py]
 2def multiply(*args):
 3    z = 1
 4    for num in args:
 5        z *= num
 6    print(z)
 7
 8multiply(4, 5)
 9multiply(10, 9)
10multiply(2, 3, 4)
11multiply(3, 5, 10, 6)

当我们运行此代码时,我们将收到每个函数调用的产品:

1[secondary_label Output]
220
390
424
5900

由于我们使用*args将变量长度参数列表发送到我们的函数中,所以我们可以在函数调用中输入尽可能多的参数。

使用 *args,您可以创建更灵活的代码,在您的函数中接受各种各样的非关键字参数。

了解 ** 四角洲

**kwargs的双星形被用来将一个关键字,变长参数(字典)(https://andsky.com/tech/tutorials/understanding-dictionaries-in-python-3)传递给函数。

args一样,kwargs可以使用任何你想要提供的论点,但是,kwargs不同于args,因为你需要分配关键字。

首先,让我们打印出我们转移到函数的**kwargs参数,我们将创建一个简短的函数来做到这一点:

1[label print_kwargs.py]
2def print_kwargs(**kwargs):
3        print(kwargs)

接下来,我们将调用函数,其中一些关键字参数传入函数:

1[label print_kwargs.py]
2def print_kwargs(**kwargs):
3        print(kwargs)
4
5print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)

让我们运行上面的程序,看看输出:

1python print_kwargs.py
1[secondary_label Output]
2{'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'}

根据您目前使用的Python 3版本,字典数据类型可能不受排序. 在Python 3.6 和以上版本中,您将收到按顺序的关键值对,但在早期版本中,这些对将以随机顺序输出。

重要的是要注意的是,一个名为kwargs的字典被创建,我们可以与它一起工作,就像我们可以与其他字典一起工作一样。

让我们创建另一个简短的程序来展示我们如何使用**kwargs。在这里,我们将创建一个函数来欢迎一个名称字典。

1[label print_values.py]
2def print_values(**kwargs):
3    for key, value in kwargs.items():
4        print("The value of {} is {}".format(key, value))
5
6print_values(my_name="Sammy", your_name="Casey")

现在我们可以运行程序并查看输出:

1python print_values.py
1[secondary_label Output]
2The value of your_name is Casey
3The value of my_name is Sammy

再次,因为字典可能没有排序,所以你的输出可能首先是CaseySammy这个名字。

现在,让我们将额外的参数传递到函数中,以表明 **kwargs 会接受无论您想要包含多少参数:

 1[label print_values.py]
 2def print_values(**kwargs):
 3    for key, value in kwargs.items():
 4        print("The value of {} is {}".format(key, value))
 5
 6print_values(
 7            name_1="Alex",
 8            name_2="Gray",
 9            name_3="Harper",
10            name_4="Phoenix",
11            name_5="Remy",
12            name_6="Val"
13        )

当我们在这一点上运行该程序时,我们将收到以下输出,这可能再次不被评级:

1[secondary_label Output]
2The value of name_2 is Gray
3The value of name_6 is Val
4The value of name_4 is Phoenix
5The value of name_5 is Remy
6The value of name_3 is Harper
7The value of name_1 is Alex

使用**kwargs为我们提供了在我们的程序中使用关键字参数的灵活性,当我们使用**kwargs作为参数时,我们不需要知道我们最终希望传递给函数多少参数。

排序论点

在函数或函数调用中排序参数时,参数必须以特定的顺序发生:

  1. 正式定位参数
  2. *args
  3. 关键字参数
  4. **kwargs

在实践中,当与*args**kwargs一起使用明确的定位参数时,您的函数将看起来如下:

1def example(arg_1, arg_2, *args, **kwargs):
2...

并且,当与位置参数以及名称的关键字参数一起工作时,除了*args**kwargs,您的函数将看起来如下:

1def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs):
2...

在创建函数时,重要的是要记住参数的顺序,以免在 Python 代码中收到语法错误。

在函数调用中使用 *args 和 **kwargs

我们还可以使用*args**kwargs来将参数转化为函数。

首先,让我们看看一个与*args的例子。

1[label some_args.py]
2def some_args(arg_1, arg_2, arg_3):
3    print("arg_1:", arg_1)
4    print("arg_2:", arg_2)
5    print("arg_3:", arg_3)
6
7args = ("Sammy", "Casey", "Alex")
8some_args(*args)

在上述函数中,有三个参数被定义为arg_1,arg_arg_3。函数将打印出这些参数中的每个参数,然后我们创建一个可迭代的变量(在这种情况下,一个 tuple,并可以通过星座语法将该变量传入函数。

当我们使用python some_args.py命令运行该程序时,我们将收到以下输出:

1[secondary_label Output]
2arg_1: Sammy
3arg_2: Casey
4arg_3: Alex

我们还可以将上述程序修改为可迭代的 列表数据类型具有不同的变量名称. 让我们还将 *args 语法与 命名参数相结合:

1[label some_args.py]
2def some_args(arg_1, arg_2, arg_3):
3    print("arg_1:", arg_1)
4    print("arg_2:", arg_2)
5    print("arg_3:", arg_3)
6
7my_list = [2, 3]
8some_args(1, *my_list)

如果我们运行上面的程序,它将产生以下输出:

1[secondary_label Output]
2arg_1: 1
3arg_2: 2
4arg_3: 3

我们将设置一个等于一个字典的变量,其中有3个关键值对(我们将在这里使用‘kwargs’,但它可以被称为任何你想要的),并将其传递到一个函数有3个参数:

1[label some_kwargs.py]
2def some_kwargs(kwarg_1, kwarg_2, kwarg_3):
3    print("kwarg_1:", kwarg_1)
4    print("kwarg_2:", kwarg_2)
5    print("kwarg_3:", kwarg_3)
6
7kwargs = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_3": "Remy"}
8some_kwargs(**kwargs)

让我们用python some_kwargs.py命令运行上面的程序:

1[secondary_label Output]
2kwarg_1: Val
3kwarg_2: Harper
4kwarg_3: Remy

当调用函数时,您可以使用*args**kwargs来传递参数。

结论

我们可以在函数定义中使用argskwargs的特殊语法,以便将可变数的参数传递给函数。

创建接受*args**kwargs的函数最适合在你预期在参数列表中的输入数量相对较小的情况下使用。

Published At
Categories with 技术
comments powered by Disqus