位置参数
位置参数(positional argument)要求调用函数时根据函数定义的参数位置来传递参数。
例如定义一个简单的加法函数sum
,有两个形参(即位置参数)。
>>> def sum(x, y):
print("params: "+str(x)+', '+str(y))
print(x+y)
# 两个参数的顺序必须一一对应
>>> sum(1,2)
params: 1, 2
3
>>> sum(2,1)
params: 2, 1
3
# 参数个数不一致会报错
>>> sum(1)
TypeError: sum() missing 1 required positional argument: 'y'
>>> sum(1,2,3)
TypeError: sum() takes 2 positional arguments but 3 were given
关键字参数
关键字参数(keyword argument)在函数调用时,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
>>> sum(x=1,y=2)
params: 1, 2
3
>>> sum(y=1,x=2)
params: 2, 1
3
>>> sum(1,y=2)
params: 1, 2
3
>>> sum(x=1,2)
SyntaxError: positional argument follows keyword argument
通过上述调用实例可知:有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序的
默认参数
用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值。
>>> def sum(x, y=0):
print("params: "+str(x)+', '+str(y))
print(x+y)
>>> def sum(x=0, y):
......
SyntaxError: non-default argument follows default argument
>>> sum(1)
params: 1, 0
1
>>> sum(1,2)
params: 1, 2
3
注意:所有位置参数必须出现在默认参数前,包括函数定义和调用
可变参数
前面的方法都是对于参数个数已知的情况,比如sum
函数只能求两个数之和,若对于多个数之和就不行了。所以,在调用函数参数不确定时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
包裹位置传递
>>> def func(*arg):
print(arg)
print(*arg)
# 参数个数随意
>>> func(1,2,3,4)
(1, 2, 3, 4)
1 2 3 4
>>> func()
()
传进的所有位置参数都会被args
变量收集,并根据传进参数的位置合并为一个元组(tuple),args
是元组类型。
包裹关键字传递
>>> def func(**kargs):
print(kargs)
print(*kargs)
>>> func(a=1,b=2,c=3)
{'a': 1, 'b': 2, 'c': 3}
a b c
传进的所有关键字参数都会被kargs
变量收集,并根据传进的键值对合并为一个字典(dict),kargs
是字典类型。
解包裹参数
*
和**
,也可以在函数调用的时候使用,称之为解包裹(unpacking)。
1、在传递元组时,让元组的每一个元素对应一个位置参数
>>> def func(x, y):
print("params: "+str(x)+", "+str(y))
>>> args = (1,2)
>>> func(*args)
params: 1, 2
2、在传递词典字典时,让词典的每个键值对作为一个关键字参数传递给函数
>>> kargs = {'x':1, 'y':2}
>>> func(**kargs)
params: 1, 2
>>> kargs = {'a':1, 'b':2}
>>> func(**kargs)
TypeError: func() got an unexpected keyword argument 'a'
注意,字典中键值必须与函数形参名相对应。
混合使用
基本原则:先位置参数,默认参数,包裹位置,包裹关键字(定义和调用都应遵循)
>>> def func(x, y, z=1, *args, **kargs):
print(x, y, z, args, kargs)
>>> func(1,2,3,4,4,4,a=1,b=2,c=3)
1 2 3 (4, 4, 4) {'a': 1, 'b': 2, 'c': 3}