Python简明教程第14节:闭包和装饰器

96
老友旧巷
2018.07.20 11:23* 字数 1307

闭包

首先还是得从基本概念说起,什么是闭包?

维基百科:

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

在Python中的定义:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

其实白话就是说,在一个函数中新定义了一个函数,且外层函数将内层函数返回。这个函数我们暂且称之为外层函数,而新定义的函数我们称之为内层函数,如果在内层函数中使用了外层函数中的变量,那么这个内层函数就是一个闭包。对应于上面的概念“引用了自由变量的函数”,自由变量就是外层函数中的变量。

比如:

闭包

关于闭包,由于理解的角度不同,也有将内层函数和被内层函数使用的外层函数中变量作为整体称为闭包的。

关于闭包的演示:

演示

其实闭包看起来和类的概念还是有点相似的,自由变量可以类比成员变量,内层函数可以类比成员函数。这时候可以认为闭包是一种相对于类概念抽象稍微浅层次的抽象,也可以说是基于函数级别的抽象。

装饰器

关于闭包最重要的也是最常用的应用应该是装饰器了。

装饰器的应用场景很多,这里可能会重点说装饰器是如何引入的。其实了解了闭包,装饰器也能很好理解。

现在比如你和朋友一起在写一个开源项目,而且这个开源项目做的还不错,很多人在用。

如果你负责的模块中有几个功能强大的函数:

几个功能强大的函数

在项目中其他人需要调用你已经完成的这些函数:

函数调用

但是其他模块开发者在使用的过程中发现有了新需求,比如在调用这个函数之前要执行权限的判断等等,但是这些内容在代码中是不存在的。

假设你现在接收到了这样的反馈,应该怎么处理?

一,让别人验证完成后调用你的函数:

验证后调用

这种方式能够完成要求,但是当你的搭档过多,假设有100个人都需要调用你这个函数的话,每个人都要改动自己调用相关的代码,这样的效率简直惨不忍睹。

二,你来负责抽取验证函数:

验证函数抽取

这样就别人可以不用进行大量的验证工作,只需要调用你的验证函数就可以了。结果调用方式就变成了这样:

调用方式

这种方式虽然减少了一定的工作量,但是还是需要别人去还代码。体验不好。

三,你负责修改原来的函数,于是乎,就是下面的情形了:

改变函数

这样别人不要改变代码,调用的方式也不必改变,还行。

这时候,你可能需要了解下开放封闭原则了。

开放是指,已经开发的代码支持扩展。

封闭是指,已经开发发代码尽量不改变。

显然,上面的方式与开放封闭原则相悖。

是时候展现真正的技术了。

如果,我们用闭包来实现呢。

闭包实现

但是怎么调用呢?

调用方式

结果验证也是符合要求的,但是还是需要调用者改动一点点的代码。

再接下来就是Python的语法糖了,@check。

闭包实现

其中:

装饰器

其实,这就是装饰器。

简单来说,Python 的装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用Python 装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能,这个新功能可以随心所欲哦。 

好了,装饰器基本的内容就先到这里,后面会深入了解装饰器。


Then,that’s all,thank you。

关注「Python旧巷」,和小编一起学习Python吧

忽而又夏
Gupao