Python 中的参数打包和解包?


如果你在 Python 中进行了一些编程,你可能在 Python 函数中见过 “**args” 和 “**kwargs” 这些词。但它们到底是什么呢?

* 和 ** 运算符执行不同的操作,根据使用场景,它们是互补的。

因此,当我们在方法定义中使用它们时,例如 -

def __init__(self, *args, **kwargs):
pass

上述操作称为“打包”,因为它将所有参数打包到一个接收该方法调用的单个变量中,该变量是一个名为 args 的元组。我们可以使用除 args 之外的其他名称,但 args 是最常见且最符合 Python 风格的做法。要了解为什么将其放入单个变量中,请考虑以下示例

假设我们有一个函数,它接受三个参数,并且我们有一个大小为 3 的列表,其中包含函数的所有参数。现在,如果我们简单地尝试将列表传递给函数,则调用不会生效并会抛出错误。

示例 1

#function which takes three argument
def func(a,b,c):
print("{} {} {}".format(a, b, c))

#list of arguments
lst = ['python', 'java', 'csharp']

#passing the list
func(lst)

结果

TypeError: func() missing 2 required positional arguments: 'b' and 'c'

一旦我们有了 'picked' 变量,就可以执行元组无法执行的操作。args[0]、args[1] 和 args[2] 分别会返回第一个、第二个和第三个参数。如果将 args 元组转换为列表,则可以修改、删除和更改列表中的项。

要将这些打包的参数传递给另一个方法,我们需要进行解包 -

def __init__(self, *args, **kwargs):
#some code here
car(VehicleClass, self).__init__(self, *args, **kwargs)
#some code below

我们再次使用 * 运算符,但这次是在方法调用的上下文中。它现在所做的是展开 args 数组,并像每个变量都是独立的一样调用该方法。以下是一个更清晰的示例 -

示例 2

def func1(x, y, z):
print(x)
print(y)
print(z)

def func2(*args):
#Convert args tuple to a list so we can do modification.
args = list(args)
args[0] = 'HTML'
args[1] = 'CSS'
args[2] = 'JavaScript'
func1(*args)

func2('Python', 'Java', 'CSharp')

结果

HTML
CSS
JavaScript

从上面的输出可以看出,我们能够在将所有三个参数传递给 func1 之前修改它们。

类似地,我们可以解决示例 1 中发现的 TypeError 消息。

示例:1_1

#function which takes three argument
def func(a,b,c):
print("{} {} {}".format(a, b, c))

#list of arguments
lst = ['python', 'java', 'csharp']

#passing the list
func(*lst)

结果

python java csharp

因此,如果我们不知道需要传递多少个参数给 Python 函数,我们可以使用打包将所有参数打包到一个元组中。

#Below function uses packing to sum unknown number of arguments
def Sum(*args):
sum = 0
for i in range(0, len(args)):
   sum = sum + args[i]
return sum

#Driver code
print("Function with 2 arguments & Sum is: \n",Sum(9, 12))
print("Function with 5 arguments & Sum is: \n",Sum(2, 3, 4, 5, 6))
print("Function with 6 arguments & Sum is: \n",Sum(20, 30, 40, 12, 40, 54))

结果

Function with 2 arguments & Sum is:
21
Function with 5 arguments & Sum is:
20
Function with 6 arguments & Sum is:
196

下面是另一个演示打包和解包用法的程序

#function with three arguments
def func1(x,y,z):
print("Argument One: ",x)
print("\nArgument Two: ",y)
print("\nArgument Three: ",z)

#Packing- All arguments passed to func2 are packed into tuple *args
def func2(*args):
#To do some modification, we need to convert args tuple to list
args = list(args)

#Modifying args[0] & args[1]
args[0] = 'Hello'
args[1] = 'TutorialsPoint'

#Unpacking args and calling func1()
func1(*args)

#Driver code
func2("I", "Love", "Coding")

结果

Argument One: Hello

Argument Two: TutorialsPoint

Argument Three: Coding

对字典使用 **

# Program to demonstrate unpacking of dictionary items using **
def func(x,y,z):
print("Dicionary first item: ",x)
print("\nDictionary second item: ",y)
print("\nDictionary third item: ",z)
d = {'x': 27, 'y': 54, 'z': 81}
func(**d)

结果

Dicionary first item: 27

Dictionary second item: 54

Dictionary third item: 81

应用场景

  • 用于套接字编程,我们需要向服务器发送未知(无限)数量的请求。

  • 用于 Django 等 Web 框架,将可变参数发送到视图函数。

  • 用于需要我们传入可变参数的包装器函数。

更新于: 2019-07-30

938 次查看

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告

© . All rights reserved.