内容简介:什么是闭包?来看看wiki的解释在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
什么是闭包?
来看看wiki的解释
在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
这个解释比较学术话,我的理解是引用了函数体外部变量的函数,叫做函数闭包,举个栗子:
def func(): a = 1 def closure(): print(a) return closure()
对于 func
这个函数来说, closure
就是一个闭包,因为 closure
引用了 func
函数体内部变量 a
,脱离了 func
谈论 closure
是没有意义的。
在python,函数闭包这一概念通过 python 装饰器落地,成为python的一大语法糖。
先来看一下使用实例
def decorator(func): print("this is decorator") return func @decorator def func(): print("this is func")
输出
this is decorator this is func
@
+ decorator
(函数名)构成了装饰器,从结果来看 decorator
函数要先于 func
函数执行,从闭包的概念上来看,可以认为 func
是 decorator
的闭包,python将这种使用行为标准化为装饰器。这里有疑问, func
并没有使用 decorator
的变量啊(这个示例里面decorator中并没有定义变量)?
别着急,我们先来看一下 func
带参数的情况。
def decorator(func): print("this is decorator") def wrapper(func_param): return func(func_param) return wrapper @decorator def func(a): print(a) func("this is func param a")
输出
this is decorator this is func param a
decorator
带参数的情况又该如何?
def decorator(decorator_param): print(decorator_param) def wrapper(func): print("this is wrapper") def sub_wrapper(*args, **kwargs): print("this is sub_wrapper") return func(*args, **kwargs) return sub_wrapper return wrapper @decorator("this is decorator param") def func(a): print(a) func("this is func param")
输出
this is decorator param this is wrapper this is sub_wrapper this is func param
可以看到,为了传递参数,需要层层闭包来实现,写法上是变得更加复杂,但是带来的好处也是很可观的:减少了重复代码
装饰器能做什么?
以上实例无一例外反映了 装饰器
(如上例中的 decorator
函数)会先于 被装饰函数
(也就是上例中的的 func
函数)执行
这有点类似于中间件的概念,比如你想在想在第一个函数执行前打印一下当时时间,写一个装饰器就可以很容易实现,就像下面这样
from datetime import datetime def decorator(decorator_param): print(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) def wrapper(func): print("this is wrapper") def sub_wrapper(*args, **kwargs): print("this is sub_wrapper") return func(*args, **kwargs) return sub_wrapper return wrapper @decorator("this is decorator param") def func(a): print(a) func("this is func param")
so easy!
ps:
在golang中, defer
函数会在当前函数退出前执行,正好和python中的装饰器功能相对应。可以对比理解。
参考:
以上所述就是小编给大家介绍的《管窥python闭包》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。