作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!
闭包(closure)是函数式编程的重要的语法结构。函数式编程是一种编程范式 (而面向过程编程和面向对象编程也都是编程范式)。在面向过程编程中,我们见到过函数(function);在面向对象编程中,我们见过对象(object)。函数和对象的根本目的是以某种逻辑方式组织代码,并提高代码的可重复使用性(reusability)。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。
不同的语言实现闭包的方式不同。Python以函数对象为基础,为闭包这一语法结构提供支持的 (我们在特殊方法与多范式中,已经多次看到Python使用对象来实现一些特殊的语法)。Python一切皆对象,函数这一语法结构也是一个对象。在函数对象中,我们像使用一个普通对象一样使用函数对象,比如更改函数对象的名字,或者将函数对象作为参数进行传递。
函数对象的作用域
和其他对象一样,函数对象也有其存活的范围,也就是函数对象的作用域。函数对象是使用def语句定义的,函数对象的作用域与def所在的层级相同。比如下面代码,我们在line_conf函数的隶属范围内定义的函数line,就只能在line_conf的隶属范围内调用。
def line_conf():
def line(x):
return 2*x+1
print(line(5)) # within the scope
line_conf()
print(line(5)) # out of the scope
line函数定义了一条直线(y = 2x + 1)。可以看到,在line_conf()中可以调用line函数,而在作用域之外调用line将会有下面的错误:
NameError: name 'line' is not defined
说明这时已经在作用域之外。
同样,如果使用lambda定义函数,那么函数对象的作用域与lambda所在的层级相同。
闭包
函数是一个对象,所以可以作为某个函数的返回结果。
def line_conf():
def line(x):
return 2*x+1
return line # return a function object
my_line = line_conf()
print(my_line(5))
上面的代码可以成功运行。line_conf的返回结果被赋给line对象。上面的代码将打印11。
如果line()的定义中引用了外部的变量,会发生什么呢?
def line_conf():
b = 15
def line(x):
return 2*x+b
return line # return a function object
b = 5
my_line = line_conf()
print(my_line(5))
我们可以看到,line定义的隶属程序块中引用了高层级的变量b,但b信息存在于line的定义之外 (b的定义并不在line的隶属程序块中)。我们称b为line的环境变量。事实上,line作为line_conf的返回值时,line中已经包括b的取值(尽管b并不隶属于line)。
上面的代码将打印25,也就是说,line所参照的b值是函数对象定义时可供参考的b值,而不是使用时的b值。
一个函数和它的环境变量合在一起,就构成了一个闭包(closure)。在Python中,所谓的闭包是一个包含有环境变量取值的函数对象。环境变量取值被保存在函数对象的__closure__属性中。比如下面的代码:
def line_conf():
b = 15
def line(x):
return 2*x+b
return line # return a function object
b = 5
my_line = line_conf()
print(my_line.__closure__)
print(my_line.__closure__[0].cell_contents)
__closure__里包含了一个元组(tuple)。这个元组中的每个元素是cell类型的对象。我们看到第一个cell包含的就是整数15,也就是我们创建闭包时的环境变量b的取值。
下面看一个闭包的实际例子:
def line_conf(a, b):
def line(x):
return ax + b
return line
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))
这个例子中,函数line与环境变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个环境变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。
如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。利用闭包,我们实际上创建了泛函。line函数定义一种广泛意义的函数。这个函数的一些方面已经确定(必须是直线),但另一些方面(比如a和b参数待定)。随后,我们根据line_conf传递来的参数,通过闭包的形式,将最终函数确定下来。
闭包与并行运算
闭包有效的减少了函数所需定义的参数数目。这对于并行运算来说有重要的意义。在并行运算的环境下,我们可以让每台电脑负责一个函数,然后将一台电脑的输出和下一台电脑的输入串联起来。最终,我们像流水线一样工作,从串联的电脑集群一端输入数据,从另一端输出数据。这样的情境最适合只有一个参数输入的函数。闭包就可以实现这一目的。
并行运算正称为一个热点。这也是函数式编程又热起来的一个重要原因。函数式编程早在1950年代就已经存在,但应用并不广泛。然而,我们上面描述的流水线式的工作并行集群过程,正适合函数式编程。由于函数式编程这一天然优势,越来越多的语言也开始加入对函数式编程范式的支持。
相关推荐
在Python的世界里,"高阶闭包"是一个高级概念,对于理解函数的内部工作原理和实现更复杂的编程逻辑至关重要。本练习题旨在帮助你深入理解和掌握Python中的高阶闭包。 首先,让我们澄清一下什么是闭包。闭包是Python...
### Python 函数进阶...以上内容涵盖了偏函数、高阶函数、返回函数、匿名函数以及闭包等 Python 中重要的函数概念和实现方法。通过这些知识点的学习和理解,可以帮助开发者更高效地编写出结构清晰、易于维护的代码。
Python函数中也可以定义函数,也就是闭包。跟js中的闭包概念其实差不多,举个Python中闭包的例子。 def make_adder(addend): def adder(augend): return augend + addend return adder p = make_adder(23) q = ...
闭包函数初探 通常我们定义函数都是这样定义的 def foo(): pass 其实在函数式编程中,函数里面还可以嵌套函数,如下面这样 def foo(): print(hello world in foo) def bar(): print(hello world in bar) 此时...
在Python编程语言中,闭包(Closure)是一种高级特性,它涉及到函数作为返回值的使用。闭包在函数式编程中扮演着重要角色,因为它们能够捕获并存储外部作用域内的变量,即使这些变量在闭包定义后不再存在。在Python...
Python中的闭包是一种重要的编程概念,它涉及到函数、作用域和引用等核心概念。闭包在Python编程中扮演着至关重要的角色,特别是在处理高阶函数、数据封装和异步编程等场景。以下是对闭包的详细解释: 1. **闭包的...
### Python高级函数实训知识点 #### 一、闭包与计算平方根 闭包是一种特殊的函数类型,它能够访问其外部作用域内的变量。在Python中,闭包通常由以下三个特征构成: 1. **存在于两个嵌套关系的函数中**:意味着...
因此当`foo`函数执行完毕后,变量`name`和`money`并没有被销毁,而是被`tell_info`函数闭包保存起来,当调用返回的`tell_info`函数时,可以正确地打印出`bill have money 100`。 总结来说,闭包是Python中一个重要...
本文实例讲述了Python闭包实现计数器的方法。分享给大家供大家参考。具体实现方法如下: 先来看看专业的解释:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将...
首先,让我们了解函数闭包。闭包是指一个函数内部定义的另一个函数,这个内部函数可以访问并修改外部函数的局部变量,即使外部函数已经执行完毕。在Python中,当内部函数引用了外部函数的非全局变量时,就会创建一个...
Python 函数式编程和高阶函数 07闭包定义及使用.mp4
Python 函数式编程和高阶函数 09闭包的特殊用途.mp4
Python作为一门多范式的语言,支持函数式编程,允许开发者使用这种风格来编写代码。 为什么使用函数式编程呢?函数式编程有若干优势。首先,函数式风格的代码没有副作用,即函数不会改变外部状态或输出之外的任何...
在Python编程中,闭包是一种强大的工具,它允许内部函数访问并可能修改外部函数的局部变量。然而,不当使用闭包可能会导致一些问题,尤其是当内部函数试图修改闭包捕获的变量时。本实例将深入探讨这些问题,并提供...
在Python编程语言中,`factor`函数通常是指用于因式分解整数的函数,但这在提供的文本中并未直接介绍。然而,我们可以从描述和部分内容中提取出几个关键知识点: 1. **参数收集与解包**: - Python允许在函数定义...
### Python函数详解 #### 一、函数定义 在Python中,函数是一段可重用的代码块,用于执行特定的任务。定义一个函数使用`def`关键字。例如: ```python def info_1(a, b, c): print(a) print(b) print(c) ``` ...
本文将深入探讨Python的基础知识,包括变量、数据类型、运算符、流程控制语句、字符串、元组、列表、字典、集合以及函数和闭包的概念。 ### 变量与数据类型 在Python中,变量是用来存储值的容器,可以随时赋值和...
### 详解Python函数的闭包问题(内部函数与外部函数详述) #### 一、闭包的基本概念 在Python中,闭包是一个重要的概念,它涉及到函数如何与其定义时所处的作用域中的变量进行交互。具体来说,当一个内部函数引用...