Python函数式编程详解(写给初学者)

所谓函数,就是把重复的代码单独的分离出来,放在⼀个公共的地⽅,便于以后可以⼀直的进⾏调⽤,这样就可以解决多次重复来编写。

在 Python 中,函数使用关机字 def 来定义。

函数式编程是众多编程范式的一种。“编程范式”一词在 1979 年被提出,代指编写程序的方法论,或者说指的是程序员对“应该如何编写程序”这个问题的看法和认知。

随着计算机技术的不断发展,先后诞生了很多种编程范式,比如当下非常流行的过程式编程(又称面向过程编程)和面向对象编程。几乎每一种编程范式都有代表性的编程语言,比如过程式编程的典型代表是 C 语言,面向对象编程的热门语言有 Java、C++、Python 等,函数式的编程语言有 Lisp、Haskell、Scala、F# 等。

所谓函数式编程,指的是程序完全由函数组成,函数可以向变量一样作为其它函数的参数,也可以作为其它函数的返回值,函数之间还可以相互调用。

通常情况下,程序的入口是接收一些参数的 main 函数,它本身由一些函数组成,这些函数又由一些更简单的函数组成。也就是说,我们可以从函数的角度构建一个程序,这就是函数式编程。

举个简单的例子,编写程序计算 (1+2)*3 的值,过程式编程的实现过程可能是这样的:

int add = 1 + 2;
int result = add * 3;

实际上,各个运算过程还可以用函数实现,例如:

res = mul(add(1 , 2) , 3);

这种编写程序的思想,就称为函数式编程。

函数式编程的特性

在函数式编程中,推崇具有以下特性的函数:

1、函数是一等公民

学习函数式编程,您会经常看到“函数是一等公民”这句话,它的含义是:函数可以像普通数据类型一样使用,可以赋值给其它变量,可以作为另一个函数的参数,也可以作为函数的返回值。

Python 也支持“函数是一等公民”的说法,比如:

def test():
    pass
a = test

test 是一个函数,我们将它赋值给了变量 a。

再比如:

def test():
    print("http://www.91yiqixue.com/python/")
def demo(value):
    value()
demo(test)

test 是一个函数,我们将它作为参数传递给了 demo 函数。

再比如:

def demo():
    def test():
        print("http://www.91yiqixue.com/python/")
    return test
ret = demo()
ret()

test 是一个函数,作为了 demo 函数的返回值。

2) 函数没有副作用

函数式编程鼓励使用没有“副作用”的函数。

所谓“副作用”,指的是函数内部除了处理传入的参数、返回处理结果外,还会进行一些不可见的修改操作,比如修改全局变量的值。

没有副作用的函数,无论调用多少次,只要传递的参数相同,都会返回相同的值,这样的函数又称“纯函数”。

举个例子:

a = 1
def test(x):
  global a
  a += x
  return a
print(test(1))
print(test(1))
print(test(1))

程序中的 test 是一个有副作用的函数,函数内部修改了全局变量 a 的值,每次传递整数 1,内部的计算结果都是不一样的。

通过这个实例可以看出,Python 允许我们定义一个不符合函数式编程规范的函数。

3) 不修改变量 

函数式编程推崇不对变量的值做修改,换句话说,变量的值一经确定,后续就不再改变。

基于这个特性,若严格以函数式编程的思想解决类似“求 n!”的问题,通常采用递归的方式实现,例如:

def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)

虽然 Python 支持函数式编程,但并没有。Python 函数式的编程风格,函数内部可以修改局部变量(参数)的值,但不推崇修改全局变量的值。

总的来说,Python 对函数式编程风格的要求并没有那么严格,它并不是一个“纯函数式”编程语言。

函数式编程的好处

1) 模块化程度高

函数式的编程思想,程序由一个个的函数拼凑而成,每个函数只负责完成一件事,模块化程度非常高。

举个简单的例子:

def add(x,y):
    return x + y
def mul(x,y):
    return x * y
res = mul(add(1,2),3)

2) 易于测试和排错

函数式思想编写出的程序,很容易测试和排错。

一旦程序中出现了错误,只需要排查某些函数的输入和输出是否正确,就可以快速找到错误原因。

测试某些函数的功能更简单,因为各个函数的运行环境是独立的,对于给定的参数,函数的计算结果是固定不变的。

3) 可组合性高

编写函数式程序的过程中,您会编写出很多不同功能的函数,有些函数可以适用于多种场景,比如一个接收文件名并返回其内容的函数。

随着时间的推移,不断地积累各种功能的函数,聚沙成塔,您会拥有一个实用的个人函数库,通过组装它们就可以拼凑出解决当前问题的程序。

如今,除了纯函数式编程语言外,很多编程语言都陆续对函数式编程做了支持,其中就包括我们学习的 Python。

Python 的一些内置函数(比如 map()、reduce()、filter() 等),一些内置模块(比如 functools、itertools 等)和一些第三方库(toolz、fn.py)都融入了函数式编程的思想,这里不再展开介绍,感兴趣的读者可自行查阅资料。

© 版权声明
THE END
喜欢就支持一下吧
点赞3赞赏
分享
评论 抢沙发
HarryPotter的头像|艾奇编程网

昵称

取消
昵称表情