变量可以指向函数:
以Python 内置的求绝对值的函数abs()为例,调用该函数用以下代码:
print abs(-10)
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
10
但是,如果只写abs呢?
>>> abs
<built-in function abs>
可见,abs(-10)是函数调用,而abs是函数本身
x = abs(-10)
print x
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
10
函数名也是变量:
传入函数:
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,
这种函数就称之为高阶函数:
def add(x, y, f):
return f(x) + f(y)
print add(-5,6,abs)
当我们调用add(-5,6,abs)时,参数x,y和f分别接收-5,6和abs,根据函数定义,
我们可以推导计算过程为:
x ==> -5
y ==> 6
f ==> abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
def f(x):
return x * x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
[1, 4, 9, 16, 25, 36, 49, 64, 81]
Process finished with exit code 0
所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,
我们不但可以计算简单的f(x)=x2
a= [1, 2, 3, 4, 5, 6, 7, 8, 9]
print a
b=map(str,a)
print b
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
[1, 2, 3, 4, 5, 6, 7, 8, 9]
['1', '2', '3', '4', '5', '6', '7', '8', '9']
filter
Python 内建的filter()函数用于过滤序列:
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次
作用于每个元素,然后根据返回值True还是False决定保留还是丢弃该元素:
def is_odd(n):
return n % 2 == 1
print filter(is_odd,[9])
为真就返回
把一个序列中的空字符串删掉,可以这么写:
def not_empty(s):
return s and s.strip()
filter(not_empty, ['A', '', 'B', None, 'C', ' '])
# 结果: ['A', 'B', 'C']
排序算法:
函数作为返回值:
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
def calc_sum(*args):
ax = 0
for n in args:
ax = ax + n
return ax
print calc_sum(1,4,7)
但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办? 可以不返回求和的结果,
而是返回求和的函数!
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
print lazy_sum(33,44,55)
f= lazy_sum(1,2,3,4,5)
print f(
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
<function sum at 0x025479F0>
15
在这个例子中,我们在函数lazy_sum中定义了函数sum,并且,内部函数sum
可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,
相关参数和变量都保存在返回的函数中,这种称为"闭包"
闭包:
注意到返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,
其内部的局部变量还被新函数引用,所以,闭包用起来简单,实现起来可不容易。
匿名函数:
当我们在传入函数时,有些时候,不需要显示地定义函数,直接传入匿名函数更方便。
由于函数也是一个对象,而且函数对象被赋值给变量,所以,通过变量也能调用该函数:
def now():
print '2013-12-25'
f = now
f()
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
2013-12-25
函数对象有一个__name__属性,可以拿到函数的名字:
def now():
print '2013-12-25'
f = now
f()
print f.__name__
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
2013-12-25
now
def log(func):
def wrapper(*args, **kw):
print 'call %s():' % func.__name__
return func(*args, **kw)
return wrapper
@log
def now():
print '2013-12-25'
now()
C:Python27python.exe C:/Users/TLCB/PycharmProjects/untitled/t1.py
call now():
2013-12-25