猿教程 Logo

Python中如何使用* args和** kwargs 3 (How To Use *args and **kwargs in Python 3)


Introduction

In function definitions, parameters are named entities that specify an argument that a given function can accept.

When programming, you may not be aware of all the possible use cases of your code, and may want to offer more options for future programmers working with the module, or for users interacting with the code. We can pass a variable number of arguments to a function by using *args and **kwargs in our code.


Understanding *args

In Python, the single-asterisk form of *args can be used as a parameter to send a non-keyworded variable-length argument list to functions. It is worth noting that the asterisk (*) is the important element here, as the word args is the established conventional idiom, though it is not enforced by the language.

Let’s look at a typical function that uses two arguments:

def multiply(x, y):
    print (x * y)

In the code above, we built the function with x and y as arguments, and then when we call the function, we need to use numbers to correspond with x and y. In this case, we will pass the integer 5 in for x and the integer 4 in for y:

def multiply(x, y):
    print (x * y)

multiply(5, 4)

Now, we can run the above code:

$ python lets_multiply.py
python lets_multiply.py

We’ll receive the following output, showing that the integers 5 and 4 were multiplied as per the multiply(x,y) function:

Output
       20

What if, later on, we decide that we would like to multiply three numbers rather than just two? If we try to add an additional number to the function, as shown below, we’ll receive an error.

def multiply(x, y):
    print (x * y)

multiply(5, 4, 3)
Output
       TypeError: multiply() takes 2 positional arguments but 3 were given

So, if you suspect that you may need to use more arguments later on, you can make use of *args as your parameter instead.

We can essentially create the same function and code that we showed in the first example, by removing x and y as function parameters, and instead replacing them with *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)

When we run this code, we’ll receive the product for each of these function calls:

Output
       20
90
24
900

Because we used *args to send a variable-length argument list to our function, we were able to pass in as many arguments as we wished into the function calls.

With *args you can create more flexible code that accepts a varied amount of non-keyworded arguments within your function.


Understanding **kwargs

The double asterisk form of **kwargs is used to pass a keyworded, variable-length argument dictionary to a function. Again, the two asterisks (**) are the important element here, as the word kwargs is conventionally used, though not enforced by the language.

Like *args, **kwargs can take however many arguments you would like to supply to it. However, **kwargs differs from *args in that you will need to assign keywords.

First, let’s simply print out the **kwargs arguments that we pass to a function. We’ll create a short function to do this:

def print_kwargs(**kwargs):
        print(kwargs)

Next, we’ll call the function with some keyworded arguments passed into the function:

def print_kwargs(**kwargs):
        print(kwargs)

print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True)

Let’s run the program above and look at the output:

$ python print_kwargs.py
python print_kwargs.py
Output
       {'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'}

Because the dictionary data type is unordered, we received the key-value pairs in a random order, but it is important to note that a dictionary called **kwargs is created and we can work with it just like we can work with other dictionaries.

Let’s create another short program to show how we can make use of **kwargs. Here we’ll create a function to greet a dictionary of names. First, we’ll start with a dictionary of two names:

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")

We can now run the program and look at the output:

$ python print_values.py
python print_values.py
Output
       The value of your_name is Casey
The value of my_name is Sammy

Again, because dictionaries are unordered, your output may be with the name Casey first or with the name Sammy first.

Let’s now pass additional arguments to the function to show that **kwargs will accept however many arguments you would like to include:

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"
        )

When we run the program at this point, we’ll receive the following output, which is again unordered:

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

Using **kwargs provides us with flexibility to use keyword arguments in our program. When we use **kwargs as a parameter, we don’t need to know how many arguments we would eventually like to pass to a function.


Ordering Arguments

When ordering arguments within a function or function call, arguments need to occur in a particular order:

In practice, when working with explicit positional parameters along with *args and **kwargs, your function would look like this:

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

And, when working with positional parameters along with named keyword parameters in addition to *args and **kwargs, your function would look like this:

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

It is important to keep the order of arguments in mind when creating functions so that you do not receive a syntax error in your Python code.


Using *args and **kwargs in Function Calls

We can also use *args and **kwargs to pass arguments into functions.

First, let’s look at an example with *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)

In the function above, there are three parameters defined as arg_1, arg_, and arg_3. The function will print out each of these arguments. We then create a variable that is set to an iterable (in this case, a tuple), and can pass that variable into the function with the asterisk syntax.

When we run the program with the python some_args.py command, we’ll receive the following output:

Output
       arg_1: Sammy
arg_2: Casey
arg_3: Alex

We can also modify the program above to an iterable list data type with a different variable name. Let’s also combine the *args syntax with a named parameter:

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)

If we run the program above, it will produce the following output:

Output
       arg_1: 1
arg_2: 2
arg_3: 3

Similarly, the keyworded **kwargs arguments can be used to call a function. We will set up a variable equal to a dictionary with 3 key-value pairs (we’ll use kwargs here, but it can be called whatever you want), and pass it to a function with 3 arguments:

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)

Let’s run the program above with the python some_kwargs.py command:

Output
       kwarg_1: Val
kwarg_2: Harper
kwarg_3: Remy

When calling a function, you can use *args and **kwargs to pass arguments.


Conclusion

We can use the special syntax of *args and **kwargs within a function definition in order to pass a variable number of arguments to the function.

Creating functions that accept *args and **kwargs are best used in situations where you expect that the number of inputs within the argument list will remain relatively small. The use of *args and **kwargs is primarily to provide readability and convenience, but should be done with care.

介绍

在函数定义中,参数是指定给定函数可以接受的参数的实体。

编程时,您可能不会意识到代码的所有可能的用例,并且可能希望为将来的程序员使用该模块或与代码交互的用户提供更多选项。 我们可以通过在我们的代码中使用* args和** kwargs,将可变数量的参数传递给函数。


理解*

在Python中,* args的单星号形式可以用作将非关键字变长参数列表发送到函数的参数。 值得注意的是,星号(*)是这里的重要元素,因为这个词是已经建立的传统习语,虽然它不是由语言来执行的。

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

def multiply(x, y):
    print (x * y)

在上面的代码中,我们使用x和y作为参数来构建函数,然后当我们调用函数时,我们需要使用与x和y对应的数字。 在这种情况下,我们将传递x的整数5和y中的整数4:

def multiply(x, y):
    print (x * y)

multiply(5, 4)

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

$ python lets_multiply.py
python lets_multiply.py

我们将收到以下输出,显示整数5和4根据乘法(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,您可以创建更灵活的代码,在函数中接受不同数量的非关键字参数。


了解** kwargs

** kwargs的双星号形式用于将关键字,可变长度的参数字典传递给函数。 再次,两个星号(**)是这里的重要元素,因为通常使用kwarg这个词,虽然不被语言强制执行。

像* 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
python print_kwargs.py
Output
       {'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark'}

因为字典数据类型是无序的,所以我们按照随机顺序接收了键值对,但是重要的是要注意,一个名为** 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
python print_values.py
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时,您的函数将如下所示:

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_和arg_3。 该函数将打印出每个参数。 然后,我们创建一个设置为可迭代(在这种情况下是一个元组)的变量,并可以将该变量传递到具有星号语法的函数中。

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

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的使用主要是提供可读性和便利性,但应该小心。