Python中如何进行*和**参数的打包与解包操作?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1164个文字,预计阅读时间需要5分钟。
Python中的*和**,能够使函数支持任意数量的参数,它们在函数定义和调用中有着不同的作用。
- 在函数定义中,*用于收集所有位置参数到一个元组中,而**用于收集所有关键字参数到一个字典中。
例如:pythondef func(*args, **kwargs): print(位置参数:, args) print(关键字参数:, kwargs)
- 在函数调用时,*用于将一个元组解包成多个位置参数,而**用于将一个字典解包成多个关键字参数。
例如:pythonfunc(1, 2, 3, a=4, b=5)这将输出:位置参数: (1, 2, 3)关键字参数: {'a': 4, 'b': 5}
python中的*和**,能够让函数支持任意数量的参数,它们在函数定义和调用中,有着不同的目的
一. 打包参数
* 的作用:在函数定义中,收集所有的位置参数到一个新的元组,并将这个元组赋值给变量args
>>> def f(*args):print(args)
>>> f()
()
>>> f(1)
(1,)
>>> f(1, 2, 3, 4)
(1, 2, 3, 4)
>>>
** 的作用:在函数定义中,收集关键字参数传递给一个字典,并将这个字典赋值给变量kwargs
>>> def f(**kwargs):print(kwargs)
>>> f()
{}
>>> f(a=1, b=2)
{'a': 1, 'b': 2}
>>>
二. 解包参数
* 的作用:在函数调用中,* 能够将元组或者列表解包成不同的参数
>>> def func(a, b, c, d):print(a, b, c, d)
>>> args = (1, 2, 3, 4)
>>> func(*args)
1 2 3 4
>>> args = [1, 2, 3, 4]
>>> func(*args)
1 2 3 4
** 的作用:在函数调用中,**会以键/值的形式解包一个字典,使其成为独立的关键字参数
>>> def func(a, b, c, d):print(a, b, c, d)
>>> kwargs = {"a": 1, "b": 2, "c": 3, "d": 4}
>>> func(**kwargs)
1 2 3 4
三. 注意
1. 在函数定义时,* 表示打包,在函数体内部, * 仍然表示解包(print(*args)实际上也算是调用了print函数)
>>> def foo(*args, **kwargs):print(args) #未解包参数
print(*args) #解包参数
>>> v = (1, 2, 4)
>>> d = {'a':1, 'b':12}
>>> foo(v, d)
((1, 2, 4), {'a': 1, 'b': 12})
(1, 2, 4) {'a': 1, 'b': 12}
2. 打包和解包并不能脱离函数而存在
表面上看并没有什么函数,实际上是有的,用的就是format的函数调用
>>> c = {"name": 'zhang', "age": 2}>>> **c
SyntaxError: invalid syntax
>>>
>>> "Name:{name}, Age:{age}".format(**c)
'Name:zhang, Age:2'
参考源码中对format函数的定义
但是这个字典解包不能用print函数输出
>>> print(**c)Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
print(**c)
TypeError: 'age' is an invalid keyword argument for this function
>>>
因为上述字典解出来的形式是这样的:
**c = name='zhang',age=2而print函数只支持*args,不支持**kwargs
3. 在ddt中的应用
@ddt.data(*all_caseDatas)中,data是一个函数,调用函数的时候,参数*all_caseDatas自动将参数列表[{}, {}, {}...]解包为{},{},{}...,在def data(*values)函数中,*会自动将各个位置参数打包成新的元组({}, {}, {}...),然后@ddt.data就可以获取每一条数据作为测试用例了
@ddt.data(*all_caseDatas)def test_my_request(self, case_data):
global global_var
if len(global_var) != 0 and case_data["request_data"] is not None:
for key, value in global_var.items():
if case_data["request_data"].find(key) != -1:
case_data["request_data"] = case_data["request_data"].replace(key, value)
四. 练习
请写出下列代码的运行结果
def f(str1, *args, **kwargs):print(str1, args, kwargs)
l = [1, 2, 3]
t = [4, 5, 6]
d = {"a":7, "b":8, "c":9}
f(1, 2)
f(1, 2, 3, "python")
f("python", a=1, b=2, c=3)
print("================")
f("python", l, d)
f("python", *t)
f("python", *l, **d)
f("python", q="winning", **d)
运行结果:
1 (2,) {}
1 (2, 3, 'python') {}
python () {'a': 1, 'b': 2, 'c': 3}
================
python ([1, 2, 3], {'a': 7, 'b': 8, 'c': 9}) {}
python (4, 5, 6) {}
python (1, 2, 3) {'a': 7, 'b': 8, 'c': 9}
python () {'a': 7, 'b': 8, 'q': 'winning', 'c': 9}
需要注意的是f("python", *t)是把列表t先解包成 4, 5, 6,然后在def f(str1, *args, **kwargs):中将4, 5, 6重新打包成新的元组(4, 5, 6)再传递给变量args
本文共计1164个文字,预计阅读时间需要5分钟。
Python中的*和**,能够使函数支持任意数量的参数,它们在函数定义和调用中有着不同的作用。
- 在函数定义中,*用于收集所有位置参数到一个元组中,而**用于收集所有关键字参数到一个字典中。
例如:pythondef func(*args, **kwargs): print(位置参数:, args) print(关键字参数:, kwargs)
- 在函数调用时,*用于将一个元组解包成多个位置参数,而**用于将一个字典解包成多个关键字参数。
例如:pythonfunc(1, 2, 3, a=4, b=5)这将输出:位置参数: (1, 2, 3)关键字参数: {'a': 4, 'b': 5}
python中的*和**,能够让函数支持任意数量的参数,它们在函数定义和调用中,有着不同的目的
一. 打包参数
* 的作用:在函数定义中,收集所有的位置参数到一个新的元组,并将这个元组赋值给变量args
>>> def f(*args):print(args)
>>> f()
()
>>> f(1)
(1,)
>>> f(1, 2, 3, 4)
(1, 2, 3, 4)
>>>
** 的作用:在函数定义中,收集关键字参数传递给一个字典,并将这个字典赋值给变量kwargs
>>> def f(**kwargs):print(kwargs)
>>> f()
{}
>>> f(a=1, b=2)
{'a': 1, 'b': 2}
>>>
二. 解包参数
* 的作用:在函数调用中,* 能够将元组或者列表解包成不同的参数
>>> def func(a, b, c, d):print(a, b, c, d)
>>> args = (1, 2, 3, 4)
>>> func(*args)
1 2 3 4
>>> args = [1, 2, 3, 4]
>>> func(*args)
1 2 3 4
** 的作用:在函数调用中,**会以键/值的形式解包一个字典,使其成为独立的关键字参数
>>> def func(a, b, c, d):print(a, b, c, d)
>>> kwargs = {"a": 1, "b": 2, "c": 3, "d": 4}
>>> func(**kwargs)
1 2 3 4
三. 注意
1. 在函数定义时,* 表示打包,在函数体内部, * 仍然表示解包(print(*args)实际上也算是调用了print函数)
>>> def foo(*args, **kwargs):print(args) #未解包参数
print(*args) #解包参数
>>> v = (1, 2, 4)
>>> d = {'a':1, 'b':12}
>>> foo(v, d)
((1, 2, 4), {'a': 1, 'b': 12})
(1, 2, 4) {'a': 1, 'b': 12}
2. 打包和解包并不能脱离函数而存在
表面上看并没有什么函数,实际上是有的,用的就是format的函数调用
>>> c = {"name": 'zhang', "age": 2}>>> **c
SyntaxError: invalid syntax
>>>
>>> "Name:{name}, Age:{age}".format(**c)
'Name:zhang, Age:2'
参考源码中对format函数的定义
但是这个字典解包不能用print函数输出
>>> print(**c)Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
print(**c)
TypeError: 'age' is an invalid keyword argument for this function
>>>
因为上述字典解出来的形式是这样的:
**c = name='zhang',age=2而print函数只支持*args,不支持**kwargs
3. 在ddt中的应用
@ddt.data(*all_caseDatas)中,data是一个函数,调用函数的时候,参数*all_caseDatas自动将参数列表[{}, {}, {}...]解包为{},{},{}...,在def data(*values)函数中,*会自动将各个位置参数打包成新的元组({}, {}, {}...),然后@ddt.data就可以获取每一条数据作为测试用例了
@ddt.data(*all_caseDatas)def test_my_request(self, case_data):
global global_var
if len(global_var) != 0 and case_data["request_data"] is not None:
for key, value in global_var.items():
if case_data["request_data"].find(key) != -1:
case_data["request_data"] = case_data["request_data"].replace(key, value)
四. 练习
请写出下列代码的运行结果
def f(str1, *args, **kwargs):print(str1, args, kwargs)
l = [1, 2, 3]
t = [4, 5, 6]
d = {"a":7, "b":8, "c":9}
f(1, 2)
f(1, 2, 3, "python")
f("python", a=1, b=2, c=3)
print("================")
f("python", l, d)
f("python", *t)
f("python", *l, **d)
f("python", q="winning", **d)
运行结果:
1 (2,) {}
1 (2, 3, 'python') {}
python () {'a': 1, 'b': 2, 'c': 3}
================
python ([1, 2, 3], {'a': 7, 'b': 8, 'c': 9}) {}
python (4, 5, 6) {}
python (1, 2, 3) {'a': 7, 'b': 8, 'c': 9}
python () {'a': 7, 'b': 8, 'q': 'winning', 'c': 9}
需要注意的是f("python", *t)是把列表t先解包成 4, 5, 6,然后在def f(str1, *args, **kwargs):中将4, 5, 6重新打包成新的元组(4, 5, 6)再传递给变量args

