所谓函数,就是把重复的代码单独的分离出来,放在⼀个公共的地⽅,便于以后可以⼀直的进⾏调⽤,这样就可以解决多次重复来编写。
在 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)都融入了函数式编程的思想,这里不再展开介绍,感兴趣的读者可自行查阅资料。