Python学习笔记(四)函数式编程

继续Python学习。本节学习Python的函数式编程。
参考资料:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819866394c3f9efcd1a454b2a8c57933e976445c0000

1、概述。
    函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
    函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
    Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
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:偏函数,通过指定已知带默认值参数函数的参数默认值来定义新的函数。例子代码如下:
import functools  
int2 = functools.partial(int, base = 2)  
print int2('10010')  
本节学习了Python在函数式编程方面的一些特性,下一节从模块开始学习。

猜你喜欢

转载自blog.csdn.net/alvin_2005/article/details/80304910