在Python中使用函数式编程的最佳实践!(2)
还有许多高阶函数能用其他方式操作函数,其中最值得一提的就是 partial,它能锁定函数的一部分参数。这种方式也叫做“currying”,这个术语来自函数式编程的先驱者 Haskell Curry:
关于 Python 中的 FP 概念的具体介绍,以及怎样优先使用函数式进行编程,我推荐 Mary Rose Cook 的这篇文章(https://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming)。 这些函数可以将许多行的循环转变成极其精简的一行代码。但是,一般的程序员也很难理解这些代码,特别是 Python 原本与英语十分类似的语法流。个人经验,我永远都记不住参数的顺序,以及每个函数的功能,尽管我查了这么多次手册。但我强烈建议尝试一下这些函数,以了解一些 FP 的概念,而且有时候我认为它们才是正确的选择,如下一节的例子所示。 修饰器 高阶函数也以修饰器的形式融入了日常的 Python 编程中。定义修饰器的方法就反映了这一点,而@符号实际上只是个语法糖,将被修饰的函数传递给修饰器作为参数。下面就定义了一个简单的修饰器,它会将给定的代码重试三次,返回第一个成功的值,或者在三次尝试都失败之后放弃并抛出最后的异常。
这个修饰器的输入和输出的类型和值完全一样,但这并不是必须的。修饰器可以添加或减少参数,也可以改变参数的类型。它们也可以通过本身的参数进行配置。我想指出的是,修饰器本身不一定是“纯函数”,它们可以(而且经常会)有副作用,只不过是恰巧使用了高阶函数而已。 就像许多中级或高级 Python 技巧一样,这个功能非常强大,但也很容易造成混乱。你必须使用 functools.wrap 修饰器进行修饰,否则调用的函数和栈跟踪中看到的函数名字会不一样。我见过一些修饰器会做一些非常复杂或非常重要的事情,如解析 json blob 中的值,或者处理认证。我还见过同一个函数或方法定义上的多层修饰器,必须掌握修饰器的应用次序才能正确理解。我认为通过利用内置的修饰器如“staticmethod”可以帮助理解,或者编写最简单的修饰器来避免大量样板代码,但如果你想让你的代码符合类型检查的话,那么尽量不要去修改输入或输出的类型。 我的建议 函数式编程很有趣,而且学习舒适区之外的编程范式能够为你带来灵活性,而且也可以让你从另一个角度考虑问题。但是,我不推荐使用 Python 时以函数式为主,特别是在旧的代码库中不要这么做。除了上面我提到的那些坑之外,还有下面的理由:
那么,我们应该使用函数式编程的哪部分呢? 纯函数 只要可能并且合理,就应该尽量保持函数“纯净”,并仔细考虑应当在何处保持改变了的状态,并仔细地标记好。这样能让单元测试变得更容易,你不需要做太多 set-up 和 tear-down,也不需要太多 mocking,而且测试用例不论执行顺序如何,都会产生预期中的结果。 下面是个非函数式的例子。
(编辑:ASP站长网) |