Python 纯函数

Python 纯函数,函数式编程简洁明了,因为函数可以用作其他函数的参数或者返回值,后续会给出很多这样的例子。

要做到这一点,函数必须是运行时环境中的头等对象。在C等语言中,函数不是运行时中的对象,然而在Python中,函数通常是通过def语句创建的对象,且其他函数可以使用。我们还可以通过创建可调用对象,或者将lambda表达式赋给变量来创建函数。

创建函数即创建一个带有属性的对象,如下所示。

>>> def example(a, b, **kw):
...     return a*b
...
>>> type(example)
<class 'function'>
>>> example.__code__.co_varnames
('a', 'b', 'kw')
>>> example.__code__.co_argcount
2

这里我们创建了一个对象:example,其为function类。此对象包含很多属性,与该函数对象关联的__code__对象也含有自己的属性。其具体实现细节不重要,重要的是Python中的函数是头等对象,我们完全可以像处理其他对象一样处理函数,比如上面的代码示例展示了函数对象的其中两个属性。

纯函数

为了提高程序可读性,使用的函数要尽量没有副作用,即所谓的“纯函数”。使用纯函数的好处包括可以通过改变求值顺序实现优化,而其最重要的优势在于概念简单、测试方便。

在Python中,编写纯函数式代码要求代码的作用域为本地,具体而言,就是避免使用global语句。nonlocal语句的使用也可能对作用域产生副作用,也应留意,虽然副作用限制在一个嵌套函数里。实际上,达到这些要求并不难。可以把纯函数看作普通的Python编程实践。

并没有简单的方法能保证Python函数没有副作用,编码时不小心违反了纯函数规则也是常有之事。如果实在担心可能违反规则,可以写一个函数,使用dis模块扫描给定函数的__code__.co_code属性,即编译后的代码,检查是否包含全局引用。它能对内部闭包和__code__.co_freevars元组方法的使用给出提示。然而为了避免极少出现的情形而运用这类复杂的技术有些得不偿失,因此后续不会展开讨论。

Python的lambda表达式是纯函数。虽然不太推崇,但确实可以通过lambda表达式创建纯函数。
lambda表达式赋给变量以创建函数的示例如下。

>>> mersenne = lambda x: 2 ** x - 1
>>> mersenne(17)
131071

lambda表达式赋给变量mersenne,即可得到一个纯函数,实际上是一个包含单一参数x,并返回单个值的可调用对象。因为lambda表达式中不能包含赋值语句,所以它总为纯函数,适用于函数式编程。

高阶函数

使用高阶函数可以使程序简洁明了。高阶函数以其他函数为参数,或者用函数作为返回值。我们可以使用高阶函数将简单的函数组合成复合函数。

以Python的max()函数为例,我们可以提供一个函数作为其参数,来改变max()函数的行为。

待处理的数据如下。

>>> year_cheese = [(2000, 29.87), (2001, 30.12), (2002, 30.6), (2003,
30.66),(2004, 31.33), (2005, 32.62), (2006, 32.73), (2007, 33.5),
(2008, 32.84), (2009, 33.02), (2010, 32.92)]

可以如下所示使用max()函数。

>>> max(year_cheese)
(2010, 32.92)

其默认行为会比较列表中的每个元组,按元组下标为0的元素比较大小,返回最大的元素所在的元组。

由于max()函数是高阶函数,因此可以添加一个函数作为其参数。这里用一个lambda表达式作为它的函数参数,如下所示。

>>> max(year_cheese, key=lambda yc: yc[1])
(2007, 33.5)

在这个例子中,max()函数用lambda表达式定义的函数作为比较依据,返回了下标为1的最大元素所在的元组。

Python提供了许多高阶函数,后面会介绍Python提供的许多高阶函数以及编写高阶函数的方法。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程