python的函数定义很简单,但灵活度很大。除了正常定义的必选参数外,还可以使用默认参数、可变参数、关键字参数,,使得函数定义出来你的接口,不但能处理复杂的参数,还可以简化调用者的代码。
1、默认参数
eg1:计算一个x2的函数
def power(x):
return x*x
当调用power函数时,必须传入有且仅有一个参数x,若要计算x3、x4、x5怎么办,可以再定义一个power3的函数,不过麻烦,可以使用power(x,n)来计算xn
def power(x,n):
s=1
while n>0:
n=n-1
s=s*x
return s
对于以上的修改可以计算任意n次方,但是旧的调用代码失败了,原因我们增加了一个参数,导致旧的代码无法正常使用,此时,默认参数就派上用场了;;
由于我们经常计算x2,所以,完全可以把第二个参数n的默认值设定为2:
def power(x,n=2):
s=1
while n>0:
n=n-1
s=s*x
return s
当调用时,power(5) , power(5,2)是等效的,输出25;;;而对于n>2的其他情况,就必须明确的传入n,比如power(5,3)
设置默认参数时,注意几点:
一是必选参数在前,默认参数在后,否则python的解释器会报错
二是如何设置默认参数;当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面,变化小的可以作为默认参数
三是最大的好处是降低调用函数的难度
默认参数实例 eg2: 写一个一年级学生注册的函数
def enroll(name , gender):
print 'name: ',name
print 'gender: ',gender
如果继续传入年龄和城市时,怎么办?如果这样会使得调用函数的复杂度大大增加,写函数,再调用函数。此时,我们可以把年龄和城市设为默认参数就方便多了
def enroll(name , gender,age=6,city='beijing'):
print 'name: ',name
print 'gender: ',gender
print 'age: ',age
print 'city: ',city
只有与默认参数不符的学生才需要提供额外的信息,像age和city
可见,默认参数降低了函数调用的难度,而一旦需要更复杂的调用时,又可以传递更多的参数来实现。无论是简单调用还是复杂调用,函数只需要定义一个
eg3:
def add_end(L=[]):
L.append('END')
return L
正常使用默认参数时,一开始结果也是对的,但是,再次调用时,结果就不对了
>>>add_end() 输出:['END']
>>>add_end() 输出:['END','END']
>>>add_end() 输出:['END','END',END]
Python函数在定义的时候,默认参数L
的值就被计算出来了,即[]
,因为默认参数L
也是一个变量,它指向对象[]
,每次调用该函数,如果改变了L
的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]
了
所以:默认参数必须指向不变对象
以上可修改为:
def add_end(L=None):
if L is None:
L=[]
L.append('END')
return L
2、可变参数:传入的参数个数是可变的
eg:给定一组数字a,b,c,......请计算a2 + b2 + c2 + ……
要定义出这个函数,必须确定输入的参数,由于参数不确定,可以把一组数字看做list或tuple传进来
def cale(number):
sum=0
for n in number:
sum=sum+n*n
return sum
把函数修改为可变参数:定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个*
号。在函数内部,参数numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数
def cale(*number):
sum=0
for n in number:
sum=sum+n*n
return sum
3、关键字参数:可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict 字典。扩展函数的功能。请看示例:
def person(name,age,**kw):
print 'name: ' , name , 'age: ' , age , 'other: ' , kw
调用:
>>>person('Bob',35,city='beijing',job='engineer')
输出:name: Bob age: 35 other: { 'city': 'Beijing','job':'engineer'}
func(*args) 代表任意长的元组作为参数(传入形参)
func(**args) 代表一个字典作为形参传入
def func2(**args):
for key in args
print (key,args[key])
传入字典,在函数func2把字典遍历出来;传入时可以func2(a=‘1’,b=‘2’,c=‘3’)
4、参数组合:在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。
定义一个函数:
def func(a, b, c=0, *args, **kw): print 'a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw调用时,python解释器自动按照参数位置和参数名把对应的参数传进去
>>> func(1, 2) 输出:a = 1 b = 2 c = 0 args = () kw = {} >>> func(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {} >>> func(1, 2, 3, 'a', 'b') 输出:
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {} >>> func(1, 2, 3, 'a', 'b', x=99) 输出:
a = 1 b = 2 c = 3 args = ('a', 'b') kw = { 'x': 99}输出:
总结:定义可变参数和关键字参数的语法:
*args 是可变参数,args接收的是一个tuple;;;可变参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
**kw 是关键字参数,kw接收的是一个dict;;;关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})