【Python】Python学习(七)函数式编程

Chapter 4 函数式编程

函数是代码的一种封装形式,通过一层层的调用,可以将复杂任务拆解。这种分解的方式可称为面向过程的程序设计,而函数是面向过程编程(Procedure Oriented Programming)的基本单元。

函数式编程(Functional Programming)可以归为是面向过程编程,但思想更为抽象,接近数学计算。

我们知道汇编语言(Assembly Language)是面向机器的程序设计语言,属于低级语言,直接控制CPU运行。而高级语言更接近数学语言和自然语言,如C/C++/Python。对于高级编程语言,越低级的抽象程度低,越贴近计算机,执行效率高,如C语言;越高级的语言抽象程度高,越贴近计算,执行效率低,如Lisp语言。

函数式编程就是抽象程度很高的编程范式。
(1)纯函数:用纯粹的函数式编程语言编写的函数是没有变量的,输入输出确定,这种纯函数被称作没有副作用。
(2)带变量的函数:由于函数内部变量状态不确定,同样输入可能有不同输出。这种函数则是有副作用。

此外,函数式编程可以把函数本身作为参数传入另一个函数。

Python允许使用变量,不是纯函数式编程语言,但是对部分函数式编程提供支持。

4.1 高阶函数

高阶函数(Higher-order function),在数学上又称为算子或泛函。高阶函数可以对其他函数进行操作,接受函数作为参数或作为输出返回。

(1)变量可以指向函数

以Python内置的求绝对值的函数abs()为例

函数调用

>>> abs(-10)
10

函数本身

>>> abs
<built-in function abs>

函数调用的结果赋值给变量

>>> x = abs(-10)
>>> x
10

函数本身赋值给变量

>>> f = abs
>>> f
<built-in function abs>

因此,函数本身也可以赋值给变量,即变量可以指向函数。

这样可以通过变量来调用函数。

>>> f = abs
>>> f(-10)
10

变量f现在已经指向了abs函数本身。直接调用abs()函数和调用变量f()完全相同。

(2)函数名也是变量

函数名可以理解成指向函数的变量。对于abs()这个函数,可以把函数名abs看成变量,它指向一个可以计算绝对值的函数。

如果变量abs指向其他对象:

>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

abs指向10后,就无法通过abs(-10)调用该函数了。因为abs这个变量已经不指向求绝对值函数而是指向一个整数10。

因此实际代码最好不要将变量名设为内置函数名,避免指向混乱的情况。

ps:abs函数实际上是定义在import builtins模块中的,所以要让修改abs变量的指向在其它模块也生效,要用import builtins; builtins.abs = 10

(3)函数作为参数传入

上面解释了变量可以指向函数,加上函数的参数能够接受变量,那么一个函数接收另一个函数作为参数,这种函数就成为高阶函数。

以下面一个高阶函数作为例子:

def add(x, y, f):
    return f(x) + f(y)

这里函数add包含3个参数,x, y, f。返回的是以x为自变量的函数 f(x) 与以y为自变量的函数f(y)的和。接受函数f作为参数和函数f作为输出返回,因此为高阶函数。

调用

add(-5, 6, abs)

相当于参数xyf分别接收-56abs

x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11

(4)函数作为返回值返回

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

可变参数的求和,定义求和函数:

def calc_sum(*args):
    ax = 0
    for n in args:
        ax = ax + n
    return ax

但是如果不需要对输入的参数立马进行求和,在后面的代码中需要再计算的话,可以不返回求和的结果而是返回求和的函数:

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

当调用lazy_sum()时,返回的不是求和结果,而是求和函数:

>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
<function lazy_sum.<locals>.sum at 0x101c6ed90>

调用函数f时,才真正计算求和的结果:

>>> f()
25

当调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数:

>>> f1 = lazy_sum(1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值