Callables

callables 指可进行调用的一切东西,翻译出来感觉不如不翻译

函数式编程的重点在于任何情况下只要参数相同,调用函数都会得到相同的结果(tautologously)。 Python 实际上提供了几种不同的方式去创建函数,或一些和函数相似的东西(比如可以被调用)。这些方法是

  • 使用 def 关键字创建的普通函数
  • 使用 lambda 关键字创建的匿名函数
  • 定义了 __call()__ 方法的类的实例
  • 函数工厂返回的闭包
  • 经过 @staticmethod 装饰或类 __dict__ 内的静态方法
  • 生成器函数

这个列表可能不是很详尽,但让人感觉有众多不同的方法来创建一些可以被调用的东西。当然,一个类实例的 一般方法也是可以被调用的,但通常使用他们时,重点放在于访问和修改那些可变状态。

Python 是一个支持多种编程范式的语言,但它的重点放在面向对象编程上。定义一个类,通常是为了生成对象, 对象就像一个数据容器,可以通过调用方法来改变其中的数据。这种风格在某些方面上与强调纯函数和不可变的 函数式编程相反。

任何访问实例状态来决定最终返回结果的方法都不是纯函数。我们所讨论的其他可调用类型也或多或少以各种方式 依赖了状态。这篇报告的作者长期以来一直在思考,是否可以在 Python 中使用一些黑魔法来明确地声明一个 纯函数。通过用一个假想的装饰器 @purefunction 来装饰,如果该函数会产生副作用则抛出异常, 但共识是似乎无法防范 Python 内部的每一个边界情况。

纯函数和无副作用代码的优点是很容易调试和测试。大部分返回结果依赖于状态的 callables 不能进行 独立上下文的检测来摸清他们的行为。举个例子,单元测试(使用 doctestunittest, 或一些诸如 py.test nose 的第三方的测试框架)可能会在某个上下文中成功,但在一些正在执行 的有状态程序中进行相同的调用会失败。当然,任何程序都至少会有某种输出(命令行、文件、数据库、网络或者 其他的),所以副作用并不能被完全的消除。只有在考虑函数式编程术语时,我们可以暂且放到一边。