在函数定义中,参数是指定给定函数可以接受的参数的命名实体。
在编程时,您可能不知道代码的所有可能用例,并且可能希望为将来与模块一起工作的程序员或与代码交互的用户提供更多选项。我们可以通过在代码中使用 *args
和 **kwargs
来向函数传递可变数量的参数。
您应该已经安装了 Python 3,并在计算机或服务器上设置了编程环境。如果您还没有设置编程环境,可以参考适用于您的操作系统(Ubuntu、CentOS、Debian 等)的本地编程环境或服务器编程环境的安装和设置指南。
在 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)<^>
现在,我们可以运行上面的代码:
python lets_multiply.py
我们将收到以下输出,显示整数 5 和 4 被按照 multiply(x,y)
函数相乘:
20
如果以后我们决定想要将三个数字相乘而不仅仅是两个,如果我们尝试向函数添加额外的数字,如下所示,我们将收到一个错误。
def multiply(x, y):
print (x * y)
multiply(5, 4, 3)
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)
当我们运行此代码时,我们将收到每个函数调用的乘积:
20
90
24
900
因为我们使用 *args
将可变长度的参数列表发送到我们的函数,所以我们能够将任意数量的参数传递给函数调用。
使用 *args
可以创建接受函数内的多个非关键字参数的更灵活的代码。
双星号形式的 **kwargs
用于将关键字的可变长度参数字典传递给函数。同样,两个星号(**
)是重要的元素,因为惯例上使用 kwargs
这个词,尽管语言没有强制执行。
与 *args
类似,**kwargs
可以接受您想要提供的任意多个参数。但是,**kwargs
与 *args
不同之处在于您需要分配关键字。
首先,让我们打印我们传递给函数的 **kwargs
参数。我们将创建一个简短的函数来实现这一点:
def print_kwargs(**kwargs):
print(kwargs)
接下来,我们将调用函数,并将一些关键字参数传递到函数中:
def print_kwargs(**kwargs):
print(kwargs)
<^>print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)<^>
让我们运行上面的程序并查看输出:
python print_kwargs.py
{'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")
现在,我们可以运行程序并查看输出:
python print_values.py
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"
)
当我们此时运行程序,我们将收到以下输出,这可能再次是无序的:
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
的示例。
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
。函数将打印出这些参数。然后,我们创建一个设置为可迭代的变量(在本例中是元组),并可以使用星号语法将该变量传递到函数中。
当我们使用 python some_args.py
命令运行程序时,我们将收到以下输出:
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)
如果我们运行上面的程序,将产生以下输出:
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
命令运行上面的程序:
kwarg_1: Val
kwarg_2: Harper
kwarg_3: Remy
在调用函数时,您可以使用 *args
和 **kwargs
来传递参数。
我们可以在函数定义中使用 *args
和 **kwargs
的特殊语法,以便向函数传递可变数量的参数。
创建接受 *args
和 **kwargs
的函数最好用于您预期参数列表中的输入数量将保持相对较小的情况。使用 *args
和 **kwargs
主要是为了提供可读性和便利性,但应谨慎使用。## 结论
我们可以在函数定义中使用 *args
和 **kwargs
的特殊语法,以便向函数传递可变数量的参数。
创建接受 *args
和 **kwargs
的函数最适合用于预期参数列表中的输入数量将保持相对较小的情况。使用 *args
和 **kwargs
主要是为了提高可读性和方便性,但应谨慎使用。