如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数:
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)则会报错:
这里我们可能会想到,既然args是一个tuple,那么下面的代码是否可以正常运行呢?答案是:可以正常运行,输出为3
在上面中,函数def fn(*args)的定义中,args形参前面只有一个*号,此时在函数fn中就可以把args当成是一个tuple。我们也可以定义如下一个函数:
该函数的形参带有两个*号,在函数内部,kwargs就是一个dictionary类型。如下:
但是在传实参时,我们需要注意,实参必须为key=value,且key必须为变量的命名规则(字母、数字、下划线),不能加引号,而且=不能换成:,value可以为任意类型的值。
当然,我们也可以把kwargs当作实参继续往下传。如果直接把kwargs当作实参传,那么它就是一个dictionary;但是我们还可以这样子用,把**kwargs当作实参传给形参带有默认值的函数:
这里我们可有会想到,那我自已定义一个dictionary,然后把**dictionary当作实参传给形参带有默认值的函数是否可以,答案是可以的,如下:
代码的输出为1 two。
但是要注意的是,dict的key一定要与函数callee的形参名称对应起来
比如下面的代码是会报错的,因为keyc与形参b名称不一样
当我们定义一个函数同时拥有形参*args与**kwargs时,*args必须放在前面。如下:
而当把args与kwargs当作实参时,args也必须放在前面,这是因为,带有默认值的形参必须放在函数形参列表的最后面。如下: