加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

在Python中使用函数式编程的最佳实践!

发布时间:2019-01-29 13:49:49 所属栏目:建站 来源:菜鸟带你学编程
导读:简介 Python 是一种功能丰富的高级编程语言。它有通用的标准库,支持多种编程语言范式,还有许多内部的透明度。如果你愿意,还可以查看 Python 的底层并修改,甚至能在程序运行的时候直接修改运行时。 我最近注意到一个有经验的 Python 程序员使用 Python
副标题[/!--empirenews.page--]

简介

Python 是一种功能丰富的高级编程语言。它有通用的标准库,支持多种编程语言范式,还有许多内部的透明度。如果你愿意,还可以查看 Python 的底层并修改,甚至能在程序运行的时候直接修改运行时。

我最近注意到一个有经验的 Python 程序员使用 Python 的新方法。就像许多 Python 新手一样,我在第一次看到 Python 时喜欢它的简单易懂的基本循环、函数和类定义的语法。在掌握了基础语法之后,我开始对高级功能感兴趣,如继承、生成器、元编程等。但是,我不太清楚它们的使用方法,经常会在不恰当的地方使用。有一段时间里我写的代码复杂又难理解。后来我反复修改,特别是需要长期在同一段代码上工作时,最终会将大部分代码慢慢改回使用基本的函数、循环、单例类。

尽管如此,那些高级功能一定有其存在的理由,它们也一定是非常重要的工具。很明显,“怎样编写优秀的代码”是个非常广泛的话题,甚至没有唯一的正确答案!相反,这篇文章的目标是一个特定的话题:Python 中函数式编程的应用。我将讨论函数式是什么,怎样在 Python 中使用,并根据我的经验介绍最佳使用方法。

什么是函数式编程?

函数式编程(简称 FP)是一种编程范式,其中最基本的元素是不可修改的值,以及不与其他函数共享状态的“纯函数”。纯函数对于给定的输入永远返回同样的输出,而且不会修改任何数据,也不会造成副作用。因此,纯函数经常与数学运算比较。例如,3+4 永远等于 7,不管同时进行了其他任何数学运算,也不管之前进行了多少次加法运算。

有了纯函数和不可修改的值,程序员就可以创建逻辑结构了。迭代可以用递归代替,因为递归才是让同一个动作多次执行的“函数式”做法。函数使用新的输入调用自己,直到参数满足某个终止条件。此外,还有高阶函数,它的输入是其他函数,返回另一个函数。我稍后会介绍这个概念。

尽管函数式编程从上世纪五十年代就出现了,而且许多语言也都实现了它,但它并没有完全地描述一门语言。Clojure、Common Lisp、Haskell 和 OCaml 都是以函数式为主的语言,也都融合了其他不同的编程语言概念,如类型系统、严格或懒惰求值等。大多数语言还用某种方法支持副作用,如写入文件、读取文件等,通常这些副作用都被仔细地标记为“不纯净”。

人们通常都认为函数式很深奥,而且与可实践性相比,它更看重优雅和简洁。大公司很少会在大规模项目上依赖于函数式为主的语言,即使要用也是在较小的范围内,远远不如其他 C++、Java、Python 等语言流行。但是,FP 实际上只是一种框架,一种考虑逻辑流的方式,它本身也有优点和缺点,而且也能与其他编程范式配合使用。

Python 支持什么?

尽管Python并不是以函数式为主的语言,但对它来说支持函数式编程也相对比较容易,因为Python中的一切都是对象。这意味着函数定义也可以赋给变量并传递。

  1. def add(a, b):  
  2.  return a + b  
  3. plus = add  
  4. plus(3, 4) # returns 7 

Lambda

通过 Lambda 表达式的语法,可以用声明式的方式创建函数。关键字 lambda 来自希腊字母,经常在正式的数学逻辑中用来描述函数和变量的虚拟绑定,即“lambda 演算”,它的历史比函数式编程还要久远。这一概念的另一个术语叫做“匿名函数”,因为 lambda 函数可以直接嵌入到行内使用,不需要事先指定名称。将匿名函数赋值给变量后,它的行为与正常函数完全一样。

  1. (lambda a, b: a + b)(3, 4) # returns 7  
  2. addition = lambda a, b: a + b  
  3. addition(3, 4) # returns 7 

lambda 函数最常见的用法就是提供给那些接受可调用对象作为参数的函数。“可调用对象”是任何能够通过括号调用的东西,具体来说有类、函数和方法。其中最常见的用法就是在对数据结构进行排序时,通过参数的键指定排序的相对顺序。

  1. authors = ['Octavia Butler', 'Isaac Asimov', 'Neal Stephenson', 'Margaret Atwood', 'Usula K Le Guin', 'Ray Bradbury']  
  2. sorted(authors, key=len) # Returns list ordered by length of author name  
  3. sorted(authors, key=lambda name: name.split()[-1]) # Returns list ordered alphabetically by last name. 

行内嵌入式 lambda 函数的缺点在于它不会在栈跟踪中显示名称,可能会给调试带来麻烦。

Functools

高阶函数是函数式编程的精华,部分由 Python 直接提供,部分通过 functools 函数库提供。你可能在大规模分布式数据分析方面听说过 map 和 reduce,但实际上它们也是最重要的两个高阶函数。map 在给定序列的每个元素上执行函数,然后返回结果的序列;reduce 使用一个函数收集序列中的每个元素,然后返回单个值。

  1. val = [1, 2, 3, 4, 5, 6]  
  2. # Multiply every item by two  
  3. list(map(lambda x: x * 2, val)) # [2, 4, 6, 8, 10, 12]  
  4. # Take the factorial by multiplying the value so far to the next item  
  5. reduce(lambda: x, y: x * y, val, 1) # 1 * 1 * 2 * 3 * 4 * 5 * 6 

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读