Python 函数式编程学习
1.decorator装饰器:
用途: 可以用来在代码执行时动态为函数增加功能,比如日志、安全功能。 可以新定义一个装饰器函数(或扩展一点:类), 然后再在这个函数里面调用被装饰的函数。这个味道有点儿像java中代理。
具体用途:
(1)打印日志 @log
(2)检测性能 @performance
(3)数据库事务 @transaction
(4)URL路由: @post('/register')
def f1(x): return x*2; def new_fn(f): def fn(x): print "call "+f.__name__+"()" #这里增加了日志功能 return f(x) return fn print new_fn(f1)(5) #如果用 f1 = new_fn(f1), 那么久彻底隐藏了f1的原始定义
python中可以使用语法糖@简化对装饰器的调用,下面代码和上面代码效果相同
def deco(func): def _deco(): print("before myfunc() called") func() print("after myfunc() called") return _deco @deco #相当于定义myfunc之后马上调用 myfunc = deco(myfunc) def myfunc(): print ("myfunc called") myfunc()
对于参数没有时,上面的代码能正常工作,因为在_deco中将参数个数写死了,如果为3个或者更多,可以如下
def log(f): def fn(*args,**kw): print "call "+f.__name__ + "()..." return f(*args,**kw) return fn @log def add(x,y,z): return x+y+z print add(1,2,3)
如果再给装饰器增加一个前缀可以这样写:
def log(prefix): def log_decorator(f): def wrapper(*args,**kw): print "[%s] %s()..." % (prefix,f.__name__) return f(*args,**kw) return wrapper return log_decorator #相当于: decorator = log("DEBUG"); my_func = decorator(my_func) @log("DEBUG") def my_func(): print "call my_func()" my_func()
2.匿名函数
高阶函数可以接收函数做参数,有些时候,我们不需要显式地定义函数,直接传入匿名函数更方便。
map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]) sorted([1, 3, 9, 5, 0], lambda x,y: -cmp(x,y))
返回函数的时候也可以返回匿名函数
3.闭包
在函数内部定义的函数和在外部定义的函数一样,只是它们不能被外部访问。
闭包的特点: 返回的函数还引用了外层函数的局部变量,所以要正确使用闭包,必须确保局部变量在函数返回后不变。由于闭包可以延迟调用,所以如果使用局部变量的话,在调用的时候可能变量已经发生了改变了。
4.偏函数
当一个函数有很多参数时,调用者需要提供多个参数,如果减少参数个数,就可以简化调用者负担。如int(),第二个参数默认为10,如果需要为2进制时可以调用 int($str,base=2); 假设需要转换大量的二进制字符串,那么每次都要这么调用比较麻烦,可以定义一个int2() 的函数
def int2(x,base=2):
return int(x,base)
为了简化这种写法引入偏函数,使用 functools.partial int2 = functools.partial(int, base=2)
import functools sorted_ignore_case = functools.partial(sorted, cmp=lambda s1, s2: cmp(s1.upper(), s2.upper())) print sorted_ignore_case(['bob', 'about', 'Zoo', 'Credit'])