背景/需求
设想这样一种情况:有一个列表,里面有四个元素;有一个函数,需要传入四个参数。那么我们可以直接将列表作为参数传入函数里面吗?当然不能。
# 参数打包解包在Python程序中的重要作用
# 定义一个函数,传入四个参数,输出这四个参数
def fun(a, b, c, d):
print(a, b, c, d)
# 设置列表
my_list = [1, 2, 3, 4]
# 直接传入列表,会提示报错
fun(my_list)
Output:
TypeError: fun() takes exactly 4 arguments (1 given)
怎么使用解包?
使用 * 解包列表,这样列表中所有的元素都能作为不同的参数传入函数中。
# 定义一个函数,传入四个参数,输出这四个参数
def fun(a, b, c, d):
print(a, b, c, d)
# 设置列表
my_list = [1, 2, 3, 4]
# 解包列表,作为参数传入函数
fun(*my_list)
Output:
(1, 2, 3, 4)
注意,函数中参数的数量必须与列表中元素的数量保持一致,这样一一对应,才可能解包成功。
# 当 len(args) != 函数所需的参数数量时,就会报错
args = [0, 1, 4, 9]
def func(a, b, c):
return a + b + c
# 使用解包的列表调用函数
func(*args)
Output:
Traceback (most recent call last): File "/home/592a8d2a568a0c12061950aa99d6dec3.py", line 10, in <module> func(*args) TypeError: func() takes 3 positional arguments but 4 were given
再举个例子,Python内置的range函数可以传入两个单独的数值:左边代表开始,右边代表结束。如果传入的数值是一个整体,需要使用 * 将参数从列表或元组中解包出来,才能传入range函数。
>>> range(3, 6) # 正常情况下,需要传入两个单独的数值
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # 解包列表,调用range函数
[3, 4, 5]
怎么使用打包?
当我们不知道需要给函数传入几个参数时,需要将全部的参数打包在一个元组中。
# 参数打包在Python程序中的重要作用
# 以下函数使用打包方法,对参数的数量进行相加运算
def mySum(*args):
return sum(args)
# 传入参数
print(mySum(1, 2, 3, 4, 5))
print(mySum(10, 20))
Output:
15
30
在上述函数,我们将所有参数打包在一个变量中。有了这个“打包过的”变量,我们就可以像使用元组一样,使用这个变量了。args[0]和args[1]可以分别返回第一个和第二个参数。由于元组内容无法修改,所以也可以将元组转换成列表,方便修改里面的元素。
打包和解包组合使用
下面这个例子将会展示打包和解包的组合使用方法。
# 参数打包解包在Python程序中的重要作用
# 定义一个函数,设置需要传入三个参数,输出这三个参数
def fun1(a, b, c):
print(a, b, c)
# 定义一个参数,将所有参数打包成元组,输入 *args 传入fun2
def fun2(*args):
# 将元组转换成列表,方便修改元素
args = list(args)
# 修改 args 的内容
args[0] = 'Geeksforgeeks'
args[1] = 'awesome'
# 解包 args,将其传入fun1函数
fun1(*args)
# 执行代码
fun2('Hello', 'beautiful', 'world!')
Output:
(Geeksforgeeks, awesome, world!)
使用 ** 打包解包字典
# A sample program to demonstrate unpacking of
# dictionary items using **
# 定义一个函数,使用 ** 为字典解包
def fun(a, b, c):
print(a, b, c)
# A call with unpacking of dictionary
d = {'a':2, 'b':4, 'c':10}
fun(**d)
Output:
2 4 10
** 可以用来解包字典内容,字典中的键需要而且一定是与函数的参数保持一致。比如,输入fun(1, **d)
,就等价于输入 fun(1, b=4, c=10)。
# 定义一个函数,使用 ** 为字典打包
def fun(**kwargs):
# 验证kwargs的类型
print(type(kwargs))
# 输出字典内容
for key in kwargs:
print("%s = %s" % (key, kwargs[key]))
# Driver code
fun(name="geeks", ID="101", language="Python")
Output:
<class 'dict'>
name = geeks
ID = 101
language = Python
运用及注意事项
- 在套接字编程中用于向服务器发送大量请求。
- 在Django框架中,用来向view函数发送变量参数。
- 有些包装函数需要传入变量参数。
- 容易进行参数的修改,但同时验证可能会发生错误,因此必须小心使用打包和解包。
参考来源
http://hangar.runway7.net/python/packing-unpacking-arguments
这篇文章由Shwetanshu Rohatgi创作。如果你喜欢 GeeksforGeeks并有意愿投稿,你可以在www.write.geeksforgeeks.org上进行创作,或者将文章发送到我们的邮箱:review-team@geeksforgeeks.org。这样你就有机会看到自己的文章发布在 GeeksforGeeks 的主页上,帮到其他的极客。
如果你发现这篇文章有任何错误之处,或者想要分享更多这方面的内容,请在评论区留言。