一、*[参数名]
调用
合法调用
普通调用
*参数名一般写成*args, 如:
def func(*args):
print(args)
可以试着调用func:
>>> func(1)
(1,)
>>> func()
()
>>> func(1, 2, 3)
(1, 2, 3)
>>> func(dict(), set(), str(), int())
({}, set(), '', 0)
所以,我们发现,这样的函数可以传任意个参数(包括0),*会把参数打包成一个tuple,如(1,) () (1, 2, 3) ({}, set(), '', 0)。
特殊调用
如果已经有一个tuple对象,想传进去作为args呢?
首先定义一个tuple对象:
>>> tuple_object = (1, 2, 3)
>>> print(tuple_object)
(1, 2, 3)
错误方法
一般想到的都是这样的方法:
>>> func(tuple_object)
((1, 2, 3),)
((1, 2, 3),)? 不应该是(1, 2, 3)吗?
因为系统把它识别为一个args中的参数,所以args就是“tuple中有tuple”,不对。OH NO!
正确方法
给tuple_object前面打个*,OK:
>>> func(*tuple_object)
(1, 2, 3)
这就是“解包”。
非法调用
如果调用func(a=1, b=2)呢?请看:
>>> func(a=1, b=2)
得到TypeError:
Traceback (most recent call last):
File "<*args test file>", line 1, in <module>
func(a=1, b=2)
TypeError: func() got an unexpected keyword argument 'a'
错误中,keyword argument是什么?
keyword argument是像a=1b=2c='Hi'这样的传参形式。- 简单地说,
keyword argument就是name=value形式的传参。
所以,应该用value形式的传参(英文是positional argument),而不应该使用name=value的传参。
默认参数
*[参数名]的参数不能有默认参数:

如上图,尝试设置默认参数会报SyntaxError,如果真要设置默认参数,应该用一种类似“手动设置默认值”的办法:
# 手动设置*args的参数默认值
DEFAULT_VALUE = (1, 2, 3) # 默认值,可自行改变
def func(*args):
if args == (): # 如果为空(用户没有传递参数):
args = DEFAULT_VALUE # 设为默认值
print(args)
这样,就有默认值了:
>>> func() # 无参数调用
(1, 2, 3)
总结
*[参数名]表示应使用value形式传参,参数个数不限,传入后会打包成tuple,供函数体使用。- 特殊传参方法:
*[tuple object] - 这种方法不能设置默认值,只能用“手动设置默认值”。
二、**[参数名]
调用
合法调用
普通调用
**参数名一般写成**kwargs, 如:
def func(**kwargs): # kwargs = keyword arguments
print(kwargs)
然后调用func,但是这个跟上一个相反,必须是name=value式传参 (这也是为什么它叫kwargs (keyword arguments)):
>>> func(a=1, b=2, c=3, d=4)
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> func(_tuple_obj=tuple(), _set_obj=set(), _dict_obj=dict())
{'_tuple_obj': (), '_set_obj': set(), '_dict_obj': {}}
>>> func()
{}
这样的函数可以传任意个keyword argument(包括0),这里也与上一个相反,会把参数打包成一个dict,如{'a': 1, 'b': 2, 'c': 3, 'd': 4} {'_tuple_obj': (), '_set_obj': set(), '_dict_obj': {}} {}。
特殊调用
如果已经有一个dict对象,想传进去作为kwargs呢?
首先定义一个这样的对象:
>>> dict_object = {'a': 666, 'b': 888}
>>> print(dict_object)
{'a': 666, 'b': 888}
然后,跟上次相似:
>>> func(dict_object) # 因为不能传positional argument, 这下还报错了(马上会讲到):
Traceback (most recent call last):
File "<**kwargs test program>", line 1, in <module>
func(dict_object)
TypeError: func() takes 0 positional arguments but 1 was given
>>> func(**dict_object) # 正确方法
{'a': 666, 'b': 888}
非法调用
如果传递positional argument呢?请看:
>>> func(1, 2)
得到TypeError:
Traceback (most recent call last):
File "<**kwargs test program>", line 1, in <module>
func(1, 2)
TypeError: func() takes 0 positional arguments but 2 were given
所以,这里应该用key=value形式的传参(英文是keyword argument),而不应该使用value的传参方法。
默认参数
与*args的方法类似,应该用手动设置默认值”的方法:
# 手动设置**kwargs的参数默认值
DEFAULT_VALUE = {'a': 1, 'b': 2} # 默认值,可自行改变
def func(**kwargs):
if kwargs == {}: # 如果为空(用户没有传递参数):
kwargs = DEFAULT_VALUE # 设为默认值
print(kwargs)
这样,就有默认值了:
>>> func() # 无参数调用
{'a': 1, 'b': 2}
总结
**[参数名]表示应使用key=value形式传参,参数个数不限,传入后会打包成dict。- 特殊传参方法:
**[dict object] - 这种方法不能设置默认值,也只能用“手动设置默认值”。


本文详细解析了Python函数中*args与**kwargs的使用方法,包括合法调用、特殊调用、非法调用及默认参数设置。通过实例演示如何正确使用这两个特性,以及在传入tuple和dict时的特殊技巧。
600

被折叠的 条评论
为什么被折叠?



