可变参数
args
如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数:
def fn(*args):
print args
可变参数的名字前面有个*
号,我们可以传入0个、1个或多个参数给可变参数。
>>> fn()
()
>>> fn(1)
(1,)
>>> fn(1, 2)
(1, 2)
>>> fn((1, 2), "one")
((1, 2), "one")
可变参数也不是很神秘,Python解释器会把传入的实参组装成一个tuple
传递给args
。因此,在函数内部,直接把变量args
看成一个tuple
就好了。实参可以是任意类型,比如上面fn((1, 2), "one")
中,(1, 2)
本身就是一个tuple
类型。
当然,我们也可以把args
当作实参继续往下传,比如:
def callee(one, two):
print one, two
def fn(*args):
callee(*args)
caller(1, 2)
上面中,callee(*args)
这行代码,Python会把*args
拆成两个实参传给callee
函数。需要注意的是,我们在调用fn
函数时只能传两个参数,如果传三个参数fn(1, 2, 3)
则会报错:
TypeError: callee() takes exactly 2 arguments (3 given)
这里我们可能会想到,既然args
是一个tuple
,那么下面的代码是否可以正常运行呢?答案是:可以正常运行,输出为3
def test(a, b):
return a + b
tup = (1, 2)
print test(*tup)
kwargs
在上面中,函数def fn(*args)
的定义中,args
形参前面只有一个*
号,此时在函数fn
中就可以把args
当成是一个tuple
。我们也可以定义如下一个函数:
def fn(**kwagrs):
print kwargs
该函数的形参带有两个*
号,在函数内部,kwargs
就是一个dictionary
类型。如下:
>>> fn()
{}
>>> fn(a=1)
{"a": 1}
>>> fn(a=1, b:"2")
{"a": 1, "b": "2"}
>>> fn(a=1, b:("one", "two"))
{"a": 1,"b": ("one", "two")}
但是在传实参时,我们需要注意,实参必须为key=value
,且key必须为变量的命名规则(字母、数字、下划线),不能加引号,而且=
不能换成:
,value可以为任意类型的值。
当然,我们也可以把kwargs
当作实参继续往下传。如果直接把kwargs
当作实参传,那么它就是一个dictionary
;但是我们还可以这样子用,把**kwargs
当作实参传给形参带有默认值的函数:
def callee(a=0, b="one"):
print a, b
def fn(**kwargs):
callee(**kwargs)
>>> fn()
0 one
>>> fn(a=1)
1 one
>>> fn(a=1, b="two")
1 two
这里我们可有会想到,那我自已定义一个dictionary
,然后把**dictionary
当作实参传给形参带有默认值的函数是否可以,答案是可以的,如下:
def callee(a=0, b="one"):
print a, b
dict = {"a": 1, "b": "two"}
callee(**dict)
代码的输出为1 two
。
但是要注意的是,dict
的key一定要与函数callee
的形参名称对应起来
比如下面的代码是会报错的,因为keyc
与形参b
名称不一样
def callee(a=0, b="one"):
print a, b
dict = {"a": 1, "c": "two"}
callee(**dict)
混合使用
当我们定义一个函数同时拥有形参*args
与**kwargs
时,*args
必须放在前面。如下:
def fn(*args, **kwargs)
print args, kwargs
而当把args
与kwargs
当作实参时,args
也必须放在前面,这是因为,带有默认值的形参必须放在函数形参列表的最后面。如下:
def callee(a, b="zero"):
print a, b
def fn(*args, **kwargs):
callee(*args, **kwargs)
>>> fn(1, b="one")
1 one
Reference
Last updated
Was this helpful?