[ python ] 函数的参数
位置参数
def power(x, n): return x ** n
站在形参的角度:
x 和 n 都是位置参数
站在实参的角度:
x 和 n 有两种传参的方法
(1)严格按照顺序进行传参
(2)按照默认参数的形式进行传参
>>> power(2, n = 4) 16 或 >>> power(n=4, x=2) 16
默认参数
在日常使用中,我们发现计算最多的都是 x 的平方,但是我们每次调用都需要传递两个参数,在这样的情况下,我们可以将 n 默认设置为 2,这就是默认参数。
>>> power(4) 16 或者 >>> power(4, n=2) 16
而对于 n > 2 的其他情况,就必须明确的传入 n 比如:power(4, n=4)
>>> power(4, n=4) 256
从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点需要注意:
(1)必选参数(位置参数)在前,默认参数在后,否则Python的解释器会报错;
(2)把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
使用默认参数可以降低调用函数的难度,但是定义默认参数要牢记一点:默认参数必须指向不变对象!
可变参数
在python函数中,还可以定义可变参数。可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
定义可变参数:
def calc(*args): n = 0 for i in args: n += i return n >>> calc(1,2,3,4,5,6) # 可以传入的参数个数是可变的 21 >>> calc(1,2,3) 6
也可以直接传入一个 list 或者 tuple,传入方式如下:
>>> li = [1,2,3,4] >>> calc(*li) 10 >>> t1 = (1,2,3,4,5,6) >>> calc(*t1) 21
关键字参数
可变参数允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个 tuple。而关键字参数允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict 。
>>> def person(name, age, **kwargs): # 关键参数定义为: **kwargs ... print('name:', name, 'age:', age, 'other:', kwargs) ... >>> person('jay', 20, city='taibei', sex='male') # 关键字参数允许传入0个或任意个含参数名的参数 name: jay age: 20 other: {'sex': 'male', 'city': 'taibei'} # 函数调用时自动组装为一个 dict
命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入什么,就需要在函数内部通过kwargs检查,如果要限制关键字参数的名字,就可以使用命名关键字参数,例如 person函数只接收 city 和 job 作为关键字参数。定义如下:
和关键字参数**kwargs不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。
>>> def person(name, age, *, city, job): ... print(name, age, city, job) ... >>> person('jay', 20, city='taibei', job='singer') jay 20 taibei singer
参数的组合
在python中定义函数,可以用位置参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是: 位置参数、默认参数、可变参数、命名关键字参数、关键字参数
比如定义一个函数,包含若干参数:
>>> def f1(a, b, c=3, *args, **kwargs): ... print('a=', a, 'b=', b, 'c=', c, 'arg=', args, 'kwargs=', kwargs) ... >>> f1('a', 'b', 'c', 'd', 'e', 'f', h='H', i='I' ,j='J') a= a b= b c= c arg= ('d', 'e', 'f') kwargs= {'i': 'I', 'j': 'J', 'h': 'H'}
小结
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过*args传入:func(*(1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过**kw传入:func(**{'a': 1, 'b': 2})。