Python函数的参数
Python函数的定义非常简单,且灵活度非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
- 位置参数
先来一个计算X2的函数:
def power(x):
return x * x
对于power(x)函数,参数x就是一个位置参数。当我们调用power函数时,必须传入有且仅有的一个参数x:
>>> power(5)
25
>>>
225
现在,如果我们要计算X3这么办?可以再定义一个power3函数,但是如果要计算X4,X5 ...怎么办?我们不可能定义无限多个函数。
那我们就来定义一个power(x,n)用来计算Xn
def power(x,n)
s = 1
while n >0:
n = n - 1
s = s * x
return s
对于修改后的power(x,n)函数,可以计算X任意n次方。
>>> power(5,2)
25
>>> power(5,3)
125
修改后的power(x,n)函数有两个参数:x和n,这两个参数都是位置参数,调用函数时,传入的两个值按照位置顺序依次赋给参数x和n。
- 默认参数
新的power(x,n)函数定义没有问题,但是,旧的调用代码失败了,原因是我们增加了一个参数,导致旧的代码因为缺少一个参数而无法正常调用:
power(5)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'n'
OK, 此时调用power提示缺少了一个位置参数"n".
这个时候默认参数就派上用场了。由于我们经常计算X2,所以,完全可以把第二个参数n的默认值设定为2:
def power(x,n=2):
s = 1
while n > 0 :
n -=1
s *= x
return s
这样,当我们调用power(5)时,就相当于调用了power(5,2):
>>> power(5)
25
>>> power(5,2)
25
而对于n>2的情况就必须传入n,比如power(5,3)。
从上面的例子可以看出,默认参数可以简化函数的使用。设置默认参数时,有几点要注意:
- 必选参数在前,默认参数在后。
- 如何设置默认参数。当函数有多个参数时,把变化大的参数放在前面,变化小的参数放在后面。变化小的参数就可以作为默认参数
- 使用默认参数有什么好处?最大的好处就是降低函数调用的难度。
- 定义默认参数必须指向不变对象。
默认参数虽好,但也有坑,<del>最大的坑来演示一下</del>:
def add_end(L=[]):
L.append('END')
return L
add_end(['x','y','z'])
['x', 'y', 'z', 'END']
add_end([1,2,3])
[1, 2, 3, 'END']
add_end()
['END']
add_end()
['END', 'END']
add_end()
['END', 'END', 'END']
正常调用似乎没有错误,但是当你重复调用的时候会出现问题了。所以要记住默认参数必须指向不变对象
要修改上面的例子我们得用None这个不变对象来实现:
def add_end(L = None):
if L == None:
L = []
L.append('End')
return L
add_end()
['End']
add_end()
['End']
add_end()
['End']
OK,这样就没有问题了。
- 可变参数
在Python中还可以定义可变参数,顾名思义,可变参数就是传入参数的个数是可变的,可以是1个2个到任意个,还可以是0个。
我们以数学题为例子,给定一组数字a,b,c...,请计算a2+b2+c2+...。
要定义这个函数,我们必须确定输入的参数。由于参数不确定,我们首先想到可以把a,b,c...,作为一个list或者tuple传进来,这样函数可以定义如下:
def calc(numbers):
sum = 0
for number in numbers:
sum += number * number
return sum
calc([1,2,3])
14
calc((4,5,6))
77
但是这样调用的时候,需要先组装出一个list或者tuple,如果利用可变参数,调用的方式就可以简化:
def calc(*numbers):
sum = 0
for number in numbers:
sum += number* number
return sum
calc(1,2,3)
14
calc(8,9,10)
245
calc()
0
定义可变参数与定义一个list或者tuple参数相比,仅仅在参数前面加了一个*号,在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数: