• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

进一步理解Python中的函数编程

python 搞代码 4年前 (2022-01-08) 13次浏览 已收录 0个评论

这篇文章主要介绍了进一步理解Python中的函数编程,本文进一步讨论了Python中函数编程的一些要点,来自IBM官方技术文档,需要的朋友可以参考下

我们最好从最难的问题开始:“到底什么是函数编程 (FP)?”一个答案可能会说 FP 就是您在使用例如 Lisp、Scheme、Haskell、ML、OCAML、Clean、Mercury、Erlang(或其它一些)语言进行编程时所做的。这是一个稳妥的答案,但不能很确切地阐明问题。不幸的是,即使是函数程序员他们自己也很难对 FP 究竟是什么有个一致的认识。“盲人摸象”的故事用来形容这一情况似乎很合适。还可以放心地将 FP 与“命令编程”(使用例如 C、Pascal、C++、Java、Perl、Awk、TCL 以及其它大多数语言所执行的操作,至少是在很大程度上)进行对比。

从个人角度来说,我会将函数编程粗略地描绘为至少具有以下几个特征。称得上函数性的语言使这些事情变得简单,而使其它事情变得困难或不可能:

  •     函数是第一类(对象)。即,可以对“数据”进行的每样操作都可以使用函数本身做到(例如将一个函数传递给另一个函数)。
  •     将递归用作主要的控制结构。在某些语言中,不存在其它“循环”构造。
  •     重点集中在列表 LISt 处理(例如,名称 Lisp )。列表经常和子列表的递归一起使用以替代循环。
  •     “纯”函数语言能够避免副作用。这不包括在命令语言中最普遍的模式,即指定第一个,然后将另一个值指定给同一个变量来跟踪程序状态。
  •     FP 不鼓励或根本不允许出现 语句,取而代之是使用表达式求值(换句话说,即函数加上自变量)。在很纯粹的情况下,一个程序就是一个表达式(加上支持的定义)。
  •     FP 关心的是计算 什么而不是 如何计算。
  •     许多 FP 利用了“更高等级”函数(换句话说,就是函数对一些函数操作,而这些函数又对其它函数操作)。

函数编程的提倡者认为所有这些特征都导致更快速的开发更短以及错误更少的代码。而且,计算机科学、逻辑和数学领域的高级理论学家发现证明函数语言和程序的正式性能比命令语言和程序容易得多。
固有的 Python 函数能力

自从 Python 1.0 以来,Python 具有上面列出的大多数 FP 特征。但对于大多数 Python 特性,它们以一种非常混合的语言呈现。很大程度上是因为 Python 的 OOP 特性,您可以使用希望使用的部分而忽略其余部分(直到在稍后需要它为止)。使用 Python 2.0, 列表内涵添加了一些 非常棒的“句法上的粉饰”。虽然列表内涵没有添加什么新的能力,但它们使许多旧的能力看起来好了 许多。

Python 中 FP 的基本元素是函数 map() 、 reduce() 和 filter() ,以及运算符 lambda 。在 Python 1.x 中, apply() 函数对于将一个函数的列表返回值直接应用于另一个函数也很方便。Python 2.0 为这一目的提供了改进的语法。可能让人吃惊,但很少的这几个函数(以及基本运算符)几乎足以编写任何 Python程序;特别是,所有的流控制语句( if 、 elif 、 else 、 assert 、 try 、 except 、 finally 、 for 、 break 、 continue 、 while 、 def )可以只使用 FP 函数和运算符以函数风格处理。虽然实际上消除程序中的所有流控制命令可能只对加入“混乱的 Python”竞争(与看上去非常象 Lisp 的代码)有用,但是理解 FP 是如何使用函数和递归来表示流控制是值得的。

消除流控制语句

在我们执行消除联系时要考虑的第一件事是 Python “短路”了布尔表达式的求值这一事实。这样就提供了表达式版本的 if / elif / else 块(假设每块都调用一个函数,通常总有可能这样安排)。下面是具体方法:
清单 1. Python 中的“短路”条件调用

 # Normal statement-based flow control if : func1() elif : func2() else :   func3() # Equivalent "short circuit" expression ( and func1()) or ( and func2()) or (func3()) # Example "short circuit" expression >>> x = 3 >>> defpr (s): return s >>> (x==1 and pr( 'one')) or (x==2 and pr( 'two')) or (pr( 'other')) 'other' >>> x = 2 >>> (x==1 and pr( 'one')) or (x==2 and pr( 'two')) or (pr( 'other')) 'two' 

表达式版本的条件性调用似乎不过是个位置诀窍;不过,如果我们注意到 lambda 运算符必须返回表达式时,就更有趣了。因为 — 如前所示 — 表达式可以通过短路来包含条件块,所以 lambda 表达式在表达条件返回值中非常普通。在我们的示例上构建:
清单 2. Python 中 Lambda 短路

 >>> pr = lambda s:s >>> namenum = lambda x: (x==1 and pr( "one")) \ .... or (x==2 and pr( "two")) \ .... or (pr( "other")) >>> namenum(1) 'one' >>> namenum(2) 'two' >>> namenum(3) 'other' 

函数作为第一类对象

上面的示例已经显示出函数在 Python 中所处的第一类的地位,但以很微妙的方式。在使用 lambda 操作创建 函数对象 时,我们有一些完全常规的事物。正是因为这样,我们可以将对象与名称 “pr” 和 “namenum” 绑定,使用的方法和将数字 23 或字符串 “spam” 与这些名称绑定的方法完全相同。但正如我们可以使用数字 23 而无需将它与任何名称绑定一样(换句话说,象函数自变量一样),我们可以使用用 lambda 创建的函数对象而不用将它与任何名称绑定。一个函数只是我们在 Python 中对其执行某些操作的另一个值。

我们对第一类对象所执行的主要操作是将它们传递给 FP 内置函数 map() 、 reduce() 和 filter() 。这些函数中的每一个都接受函数对象作为其第一个自变量。

    map() 对指定列表中每个对应的项执行传递的函数,并返回结果列表。
    reduce() 对每个后续项执行传递的函数,返回的是最终结果的内部累加;例如 reduce(lambda n,m:n*m, range(1,10)) 意味着“10 的阶乘”(换句话说,用每一项乘上前一次相乘的乘积)。
    filter() 使用传递的函数对列表中的每一项“求值”,然后返回经过甄别的,通过了传递函数测试的项的列表。

我们还经常将函数对象传递给自己的定制函数,但它们通常等同于上述内置函数的组合。

通过将这三种 FP 内置函数进行组合,可以执行惊人的一系列“流”操作(都不使用语句,而只使用表达式)。

Python 中的函数循环

替换循环与替换条件块一样简单。 for 可以直接转换成 map() 。对于我们的条件执行,我们需要将语句块简化成单一函数调用(我们正逐步接近通常的做法):
清单 3. Python 中的函数 ‘for’ 循环

 for e in lst: func(e) # statement-based loop map(func,lst) # map()-based loop 

另外,对于连续程序流的函数方法有类似的技术。即,命令编程通常包含接近于“做这样,然后做那样,然后做其它事。”这样的语句。 map() 让我们正好做到这一点:
清单 4. Python 中的函数连续操作

 # let's create an execution utility function do_it = lambda f: f() # let f1, f2, f3 (etc) be functions that perform actions map(do_it, [f1,f2,f3]) # map()-based action sequence 

通常,我们的整个 main 程序可以是 map() 表达式和一系列完成程序所需要执行的函数。第一类函数的另一个方便的特性就是可以将它们放在一个列表中。

while 的转换稍微复杂了一些,但仍然可以直接进行:
清单 5. Python 中的函数 ‘while’ 循环

 # statement-based while loop while :  if : break else :  # FP-style recursive while loopp defwhile_block ():  if : return 1 else :  return 0 while_FP = lambda : ( and while_block()) or while_FP() while_FP() 

while 的转换仍需要 while_block() 函数,它本身包含语句而不仅仅是表达式。但我们需要对该函数做进一步的消除(例如对模板中的 if/else 进行短路)。另外,因为循环主体(按设计)无法更改任何变量值,所以 来源gaodai$ma#com搞$$代**码网很难用在一般的测试中,例如 while myvar==7 (那么,将在 while_block() 中修改全部内容)。添加更有用条件的一个方法是让 while_block() 返回一个更有趣的值,然后将这个返回值与终止条件进行比较。有必要看一下这些消除语句的具体示例:
清单 6. Python 中的函数 ‘echo’ 循环

 # imperative version of "echo()" defecho_IMP (): while 1: x = raw_input( "IMP -- ") if x == 'quit': break else print x echo_IMP() # utility

以上就是进一步理解Python中的函数编程的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:进一步理解Python中的函数编程

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址