《笨办法学Python》(25)---python与函数式编程(泛函编程) FP:Functional Progaming 学习

版权声明:一起学习,一起成长,欢迎关注犀牛先生的博客 https://blog.csdn.net/xuemanqianshan/article/details/85194249

参考文档

其他参考

https://www.cnblogs.com/zhenw/p/6160931.html

https://baijiahao.baidu.com/s?id=1571513465775216&wfr=spider&for=pc

https://blog.csdn.net/u013007900/article/details/79104110

http://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html

https://www.zhihu.com/question/28292740

https://blog.csdn.net/gitchat/article/details/78651232

举例说明了

https://www.cnblogs.com/chulung/p/5651185.html#undefined    

命令式编程,声明式编程,函数式编程

https://www.cnblogs.com/sirkevin/p/8283110.html

命令式编程:关注计算机计算的步骤,一步一步的告诉计算机怎么做

声明式编程:代码只关心要做什么,不写怎么做

函数式编程:代码只关心要做什么,不写怎么做

百度科学百科

https://baike.baidu.com/item/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/4035031?fr=aladdin

函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。 

和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。

和过程化编程相比,函数式编程里函数的计算可随时调用。

简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。

它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用

廖雪峰网站:

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014317848428125ae6aa24068b4c50a7e71501ab275d52000

函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

而函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。

我们首先要搞明白计算机(Computer)和计算(Compute)的概念。

在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。

而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。

对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

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


 

什么是函数式编程 FP:Functional Progaming(高度抽象--科学应用多)

(1)  函数式编程是什么?

         "函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。

           函数本来就是是面向过程编程的基本单元,通过函数一层层的调用,复杂任务分解为简单的。但是函数式编程并不是面向过程的。函数式编程,也是结构化编程的一种

(2) 函数式编程:核心思想

          函数式编程,主要思想是把运算过程尽量写成一系列嵌套的函数调用。把计算机运算看成 纯函数的运算,基础是λ演算(lambda calculus),函数式编程,需要可以把函数当参数传递,也可以返回函数,

         函数式编程,选择对过程进行抽象,将数据以输入输出流的方式封装进过程内部,从而也降低系统的耦合度。

         数据在抽象的过程内部,变成I/O流和参数

(3)python与函数式编程

           python的所有内容都是对象,函数可以当做参数传递和返回,支持函数式编程。

          函数式编程,需要纯函数,不要变量。抽象度很高,认为函数之间传递,没有变量,没有副作用?但是python有变量,所以python不是纯函数式编程

(4) 一个函数的输出不受外部环境影响,同时也不影响外部环境时,该函数就是纯函数。

函数式编程的特性

(1) 函数是第一等公民:first class 

         函数和其他数据类型地位一样,如python里都是对象。可以直接赋值给变量,可以作为参数,可以作为返回值。

(2)闭包 closure

   闭包是起函数的作用并可以像对象一样操作的对象。

(3)仿函数 functor

(4)高阶函数

       高阶函数可以用另一个函数(间接地,用一个表达式) 作为其输入参数,在某些情况下,它甚至返回一个函数作为其输出参数。这两种结构结合在一起使得可以用优雅的方式进行模块化编程,这是使用 FP 的最大好处

(5)惰性计算(缓求值)

在惰性计算中,表达式不是在绑定到变量时立即计算,而是在求值程序需要产生表达式的值时进行计算。延迟的计算使您可以编写可能潜在地生成无穷输出的函数。因为不会计算多于程序的其余部分所需要的值,所以不需要担心由无穷计算所导致的 out-of-memory 错误

     我理解,generator 生成器是不是就是这个?

(6)递归,尾递归(调用,尾调用)

尾调用是在函数的尾部,调用另一个函数,因为函数是语言没有循环,递归很重要,对于递归需要来不断优化,一般采用尾调用或尾递归来优化。

顾名思义,尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部 ,尾递归就是把当前的运算结果(或路径)放在参数里传给下层函数和普通递归区别在于内存占用。
 

(7)匿名函数

匿名函数即lambda表达式函数

(8)柯里化
通俗的理解是将函数的参数变为一个参数的形式,函数式编程提倡柯里化编程,尽量编写一个参数的函数,优化方便,简化代码。

(8)语法糖
指程序的可阅读性更高、可以给我们带来方便,更简洁的写法,提高开发编码效率。

某种语言中添加了某种语法,这种语法对功能没有影响,但可以提高可阅读性、间接性等,则称这种语法为该语言的语法糖
 

函数式编程的特点

(1)只用"表达式",不用"语句"

"表达式"(expression)是一个单纯的运算过程,总是有返回值;

"语句"(statement)是执行某种操作,没有返回值。

函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。

(2)没有"副作用"

"副作用"(side effect),指的是函数内部与外部互动(比如修改全局变量的值),产生运算以外的其他结果。

函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。

(3)不修改状态

函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。

在其他类型的语言中,变量往往用来保存"状态"(state)。不修改变量,意味着状态不能保存在变量中。函数式编程使用参数保存状态,最好的例子就是递归。

(4)引用透明性

函数程序通常还加强引用透明性,即如果提供同样的输入,那么函数总是返回同样的结果。

就是说,表达式的值不依赖于可以改变值的全局状态。

这使您可以从形式上推断程序行为,因为表达式的意义只取决于其子表达式而不是计算顺序或者其他表达式的副作用。

(5)副作用

副作用是修改系统状态的语言结构。因为 FP 语言不包含任何赋值语句,变量值一旦被指派就永远不会改变。而且,调用函数只会计算出结果 ── 不会出现其他效果。因此,FP 语言没有副作用。 

优点:

 (1)适合“并发”在函数式编程中,由于数据全部都是不可变的,所以没有并发编程的问题,是多线程安全的。

(2)函数式编程的表达方式更加符合人类日常生活中的语法,代码可读性更强。实现同样的功能函数式编程所需要的代码比面向对象编程要少很多,代码更加简洁明晰。

(3) 函数式编程广泛运用于科学研究中,因为在科研中对于代码的工程化要求比较低,写起来更加简单,所以使用函数式编程开发的速度比用面向对象要高很多(更适合非工程化量级?)

(4)易于热更新

缺点:

(1) 耗费机器资源

面向对象编程--(更加具体和形象,工程用的多,易于上手理解)

FP:是面对过程的抽象

oop: 是面对对象的抽象

哪些部分应当设计成“不变”,哪些部分应当设计成“可变”,在这个取舍过程中FP和OOP选择了2种路径

Object-oriented programming,缩写:OOP

而在面向对象编程中,面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程范型,同时也是一种程序开发的方法。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。

(1)程序里所有内容被设计为相关的对象,对象,类。

(2)对象是类的实例,new一下

(3)面向对象对数据进行抽象,数据被抽象为对象

        将行为对象方法的方式封装到数据实体内部,从而降低系统的耦合度。

OOP的优点

在面向对象编程的基础上发展出来的23种设计模式广泛应用于现今的软件工程中,极大方便了代码的书写与维护。

 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

OOP的缺点

(1)面向对象编程以数据为核心,所以在多线程并发编程中,多个线程同时操作数据的时候可能会导致数据修改的不确定性。

(2)面向对象虽然开发效率高但是代码的运行效率比起面向过程要低很多,这也限制了面向对象的使用场景不能包括那些对性能要求很苛刻的地方。

猜你喜欢

转载自blog.csdn.net/xuemanqianshan/article/details/85194249