Python - 参数打包与解包

背景/需求

设想这样一种情况:有一个列表,里面有四个元素;有一个函数,需要传入四个参数。那么我们可以直接将列表作为参数传入函数里面吗?当然不能。

# 参数打包解包在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

运用及注意事项

  1. 在套接字编程中用于向服务器发送大量请求。
  2. 在Django框架中,用来向view函数发送变量参数。
  3. 有些包装函数需要传入变量参数。
  4. 容易进行参数的修改,但同时验证可能会发生错误,因此必须小心使用打包和解包。

参考来源

http://hangar.runway7.net/python/packing-unpacking-arguments
这篇文章由Shwetanshu Rohatgi创作。如果你喜欢 GeeksforGeeks并有意愿投稿,你可以在www.write.geeksforgeeks.org上进行创作,或者将文章发送到我们的邮箱:review-team@geeksforgeeks.org。这样你就有机会看到自己的文章发布在 GeeksforGeeks 的主页上,帮到其他的极客。
如果你发现这篇文章有任何错误之处,或者想要分享更多这方面的内容,请在评论区留言。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值