在Python中,函数传递参数一般有四种形式:
1、 位置参数:fuc1(a,b,c)
2、 默认参数:fuc2(a=1,b=2,c=3)
3、 可变参数:fuc3(*args)
4、 关键字参数:fuc4(**kw)
位置参数: 这是最常见的定义方式,一个函数可以定义任意个参数,每个参数间用逗号分割,用这种方式定义的函数在调用的的时候也必须在函数名后的小括号里提供个数相等的 实际参数,而且顺序必须相同,也就是说在这种调用方式中,形参和实参的个数必须一致,而且必须一一对应。例 如:
def fuc1(a,b,c):
print(a,b,c)
调用该函数:fuc1(1,2,3)
则a
取1
,b
取2
,c
取3
,形参与实参相对应,如果使用fuc1(1)
或者fuc1(1,2)
则会报错。
默认参数:根据键值对的形式做实参与形参的匹配,通过这种式就可以忽略了参数的位置关系,直接根据关键字来进行匹配;同时该种传参方式还有个好处就是在调用函数的时候,可以把函数参数作为可选项,不要求数量上的相等,即可以fuc2(3,4)
来调用fuc2
函数,这里关键就是前面的3,4
覆盖了原来a、b
两个形参的值,但c
还是不变采用原来的默认值3
,这种模式相较第一种更加灵活,不仅可以通过fuc2(c=5,a=6,b=7)
来打乱形参的位置,而且可以在没有对应形参传递的时候,用定义函数时的默认值,大大降低了函数调用的复杂度。
def fuc2(a=1,b=2,c=3):
print(a,b,c)
可以采用:fuc2(2,4)
、fuc2(c=8)
、fuc2(b=4,a=3,c=9)
等方式调用。
默认参数这里有个坑需要我们注意:
def add_end(L=[]):
L.append('END')
return L
当你正常调用时,结果似乎没有错:
>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end(['x', 'y', 'z'])
['x', 'y', 'z', 'END']
当你使用默认参数调用时,一开始结果也是对的:
>>> add_end()
['END']
但是,再次调用add_end()
时,结果就不对了:
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
原因解释如下:
Python
函数在定义的时候,默认参数L
的值就被计算出来了,即[]
,因为默认参数L
也是一个变量,它指向对象[]
,每次调用该函数,如果改变了L
的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]
了。
要修改上面的例子,我们可以用None
这个不变对象来实现:
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
现在,无论调用多少次,都不会有问题:
>>> add_end()
['END']
>>> add_end()
['END']
可变参数:上面两个方式在定义函数时就设定了函数参数的个数,但有时候会不确定有多少个参数,那么第三种方式就比较有用。它以一个*
加上形参名的方式来表示这个函数的形参个数不定,可能为0
个也可能为n
个。注意一点是,不管有多少个,在函数内部都被存放在以形参名为标识符的tuple
中。
如果已经有一个list
或tuple
,要调用一个可变参数的函数时,可以采用在list
或tuple
前面加一个*
号,把list
或tuple
的元素变成可变参数传进去。
def fuc3(*agrs):
If len(agrs) == 0:
print(“None”)
else:
print(agrs)
fuc3() #output: None
fuc3(1) #output: (1,)
lst = [1,2,3]
fuc3(*lst) #output: (1,2,3)
关键字参数:这种方式最为灵活,其是以键值对字典的形式向函数传参,含有第二种位置的灵活的同时具有第三种方式的数量上的无限制。
和可变参数类似,也可以先组装出一个dict
,然后把该dict
转换为关键字参数传进去,只需在实参前面加上**
。这里要注意,使用**dict
的方式传参进入函数,函数获得的是该dict
的一份拷贝,函数中的修改不会影响到实参。
def fuc4(**kw):
if len(kw) == 0:
print(“None”)
else:
print(kw)
fuc4(a=1,b=2)
mydict = {'a':1,'b':2}
fuc4(**mydict)
混合使用上述参数时要注意:参数定义的顺序必须是:位置参数、默认参数、可变参数、关键字参数。
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
在函数调用的时候,Python
解释器自动按照参数位置和参数名把对应的参数传进去。
>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
参考:
http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000