一、简述python闭包又称为词法闭包或者函数闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
因此python闭包函数必须满足两个条件:
函数内部定义了函数内部函数包含对部作用域而非全局作用域的引用。二、实例1、实例一:以下仅仅在函数内部定义了一个函数,但并非闭包函数
def outer(): def inner(): print("inner func excuted") inner() # 调用执行inner()函数 print("outer func excuted")outer() # 调用执行outer函数####输出结果为##########inner func excutedouter func excuted2、实例二:以下函数内部定义了一个函数,而且内部函数也引用了一个外部变量x,但也还不是闭包函数
x = 1def outer(): def inner(): print("x=%s" %x) # 引用了一个非inner函数内部的变量 print("inner func excuted") inner() # 执行inner函数 print("outer func excuted")outer()#####输出结果########x=1inner func excutedouter func excuted3、实例三:上面的实例已经快满足闭包函数的条件。现在,应该有了初步认识,作为一个闭包函数,必须得满足上述的两个条件,缺一不可。
def outer(): x = 1 def inner(): print("x=%s" %x) print("inner func excuted") inner() print("outer func excuted")outer()#####输出结果#########x=1inner func excutedouter func excuted4、实例4:一般情况下,我们都会给闭包函数返回一个值,这里先不说为什么,在接下来的内容中,你会看到这个返回值的用途。
def outer(): x = 1 def inner(): print("x=%s" %x) print("inner func excuted") print("outer func excuted") return inner # 返回内部函数名 outer()5、现在我们来抽象的定义一下闭包函数。它是函数和与其相关的引用环境组合而成的实体。在实现深约束时,需要创建一个能显式表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来就成为闭包。在上面实例中,我们可以发现,闭包函数必须包含自己的函数以及一个外部变量才能真正称得上是一个闭包函数。如果没有一个外部变量与其绑定,那么这个函数不能算得上是闭包函数。
那么怎么知道一个闭包函数有多少个外部引用变量呢?看看下面代码
def outer(): x = 1 y = 2 def inner(): print("x= %s" %x) print("y= %s" %y) print(inner.__closure__) return innerouter()######输出结果#######(, )结果表明,在inner内部,引用了两个外部局部变量。如果引用的是非局部变量,那么这里输出的为None.
闭包函数的特点:
自带作用域 延迟计算那么闭包函数有什么作用呢?我们清楚地知道,闭包函数在定义时,一定会绑定一个外部环境。这个整体才能算得上是一个闭包函数,那么我们可以利用这个绑定特性,来完成某些特殊的功能。
6、根据传入的URL,来下载页面源码
from urllib.request import urlopendef index(url) def get() return urlopen(url).read() return getpython = index("http://www.python.org") # 返回的是get函数的地址print(python()) # 执行get函数《并且将返回的结果打印出来baidu = index("http://www.baidu.com")print(baidu())有人可能会说,这个不满足闭包函数的条件啊!我没有引用非全局的外部变量啊。其实并非如此,只要在函数内部的变量都属于函数。在index(url),这个url也属于函数内部变量,所以上面那个函数也是闭包函数。