继续Python学习。本节学习Python的函数式编程。
参考资料:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819866394c3f9efcd1a454b2a8c57933e976445c0000
参考资料:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819866394c3f9efcd1a454b2a8c57933e976445c0000
1、概述。
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
2、Python内建了Map和Reduce函数。
map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。举例如下:
2、Python内建了Map和Reduce函数。
map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。举例如下:
def f(x): y = x * x return y r = range(10)[1:] print map(f, r)
reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)。举例如下:
#利用reduce函数计算序列的乘积 def prod(x, y): return x * y r = range(10)[1:] print reduce(prod, r)3、filter(过滤)
Python内建的filter函数允许按照传入函数返回值的真假来过滤给定的序列,调用格式为:filter(f,L),f为函数,L为要过滤的序列。举例如下:
#利用filter函数返回1-100间的素数。 import math r = range(101)[1:] def isSuS(x): if x <= 1: return False n = 2 m = math.sqrt(x) while n <= m: if x % n == 0: return False n = n + 1 return True print filter(isSuS, r)4、sorted(排序)
Python内建的sorted函数可实现按照自定义算法对给定序列进行排序。举例如下:
#利用sorted实现给定序列的倒序排序 def compare_reversed(x, y): if x > y: return -1 if x < y: return 1 return 0 print sorted([1, 3, 5, 7, 9], compare_reversed)5、函数作为返回值
例子代码如下:
def returnF(*x): def f(): m = 0 for n in x: m = m + n return m return f ff = returnF(1, 3, 5, 7, 9) print ff print ff()6、用于简化代码(函数定义)的lambda(匿名函数)
例子代码如下:
f = lambda x, y: x * y print f(1, 2)7、装饰器(Decorator)
最典型的用法是在函数调用前后自动打印日志,但又不用修改该函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。例子代码如下:
#import functools #定义一个装饰器函数log,用于在所装饰函数执行前后输出日志 def log(func): #该行代码可确保在函数执行时不改变函数的名称,也可以不加 @functools.wraps(func) def wrapper(*args, **kw): print 'begin call(%s):' % func.__name__ func(*args, **kw) print 'end called(%s):' % func.__name__ return func return wrapper #装饰器用@标识 @log #要装饰的函数 def now(): print '2018-05-11' #执行函数 now()再来一个例子:
#下面的代码,同名装饰器可以同时支持带参数和不带参数两种方式 import functools def log(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print '%s(%s)' % ('call' if callable(text) else text, func.__name__) func(*args, **kw) return wrapper return decorator(text) if callable(text) else decorator #不带参数的装饰器 @log #带参数的装饰器 @log('execute') def now(): print '2018-05-11' now()注:在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。
decorator可以增强函数的功能,定义起来虽然有点复杂,但使用起来非常灵活和方便。
8、functools.partial:偏函数,通过指定已知带默认值参数函数的参数默认值来定义新的函数。例子代码如下:
8、functools.partial:偏函数,通过指定已知带默认值参数函数的参数默认值来定义新的函数。例子代码如下:
import functools int2 = functools.partial(int, base = 2) print int2('10010')本节学习了Python在函数式编程方面的一些特性,下一节从模块开始学习。