一、函数定义
定义:def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
例如:
def my_abs(x):
ifx >=0:
return x
else:return-x
二、函数参数
函数参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数
必选参数,
默认参数,是必选参数在前,默认参数在后。当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数默认参数必须指向不变对象!
可变参数,传入的参数个数是可变的,由于参数个数不确定,所以把参数当作list或tuple传递进来。
例:def calc(numbers):
sum =0
for n in numbers:
sum = sum + n * n
return sum
关键字参数,允许传入0个或任意个含参数名的参数,在函数内部自动组装为一个dict。例如:
def person(name, age, **kw):
print 'name:', name,'age:', age,'other:', kw
三、递归函数
在函数内部,可以调用其它函数。递归函数的优点是定义简单,逻辑清晰。使用递归函数需要注意防止栈溢出。
尾递归是指,在函数返回的时候,调用自身本身。
例如:def fact(n):
ifn==1:
return1
returnn * fact(n -1)
在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。通过尾递归可以解决栈溢出。
上面的函数用尾递归的写法:
def fact(n):
return fact_iter(n,1)
def fact_iter(num, product):
if num ==1:
return product
return fact_iter(num -1, num * product)
Python解释器没有对尾递归做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出
四、高阶函数
变量可以指向函数,比如python的内置函数可以赋值给一个变量,f=abs f(-10)可以得到10;
函数名也是变量名;把abs指向10后,就无法通过abs(-10)调用该函数了!因为abs这个变量已经不指向求绝对值函数了,而是指向了固定值10。abs函数实际上是定义在__builtin__模块中的,所以要让修改abs变量的指向在其它模块也生效,要用__builtin__.abs = 10。
传入函数,一个函数可以接受另一个函数作为参数,这种函数称之为高阶函数。例如:
defadd(x, y, f):
returnf(x) + f(y)
map(f,[]);传入两个参数,第一个是函数,第二个是要进行计算的list,结果返回一个list。
filter();接收一个函数和一个序列,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
sorted();可以对list内部元素的大小进行排序。通常规定,对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1。对字符串排序是按照ASCII的大小比较的。
返回函数;把函数作为结果值返回。例如:
def lazy_sum(*args):
def sum():
ax =0
for n in args:
ax = ax + n
return ax
return sum
说明:调用lazy_sum()时返回求和函数sum(),内部函数sum还可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种程序结构称为“闭包”。注意:lazy_sum中每次调用都会返回一个新的函数,即使传入的参数相同。
返回闭包时牢记:返回函数不要引用任何循环变量,或者后续会发生变化的变量。