有过开发经验得朋友队装饰模式这个词应该不陌生,装饰装饰,顾名思义就是指对我们原来有得东西进行装饰,比如我们买了新房,那么我们对毛坯房的装修,就是对我们房子进行拓展,让它更加完善!同样得对于代码也是如此,我们就是对我们原有的功能进行功能的拓展!
一、假设我们有下面的一个场景
def test1():
print("====给员工加薪了!====")
def test2():
print("====出新版本,杀一个程序员祭天!====")
很好,同事们调得很舒服,系统跑得很好,老板赚钱。。。
def test1():
if ROLE == "boss":
print("====给员工加薪了!====")
else:
print("====不好意思,您不是老板====")
def test2():
if ROLE == "boss":
print("====出新版本,杀一个程序员祭天!====")
else:
print("====不好意思,您不是老板====")
4、这一切看起来很正常,但是我们不妨假设下,如果有10000个类似得功能函数需要添加类似得验证、又或者添加其它的功能呢?我们姑且假设你单身多年得手速非常快,但是这样搞法也是很浪费时间的吧?更何况贸然得去改动原来得代码,风险也是不小的,所以我们换下面这种方式看看!
二、闭包得引入
1、之前我已经分享过闭包的学习笔记了,不了解的可以去看下,闭包得几个条件如下:一个函数内定义了内函数,并且内涵是使用了外函数的局部变量,最后外函数返回了内涵的引用。满足了这三个条件我们就可以称之为闭包。
2、那么我们到底引入闭包做什么呢?闭包又是如何解决我们上面的问题得呢?我们先看下下面这段代码:
def iwapper(fun):
inner():
if ROLE == "boss":
print("====身法验证通过====")
fun()
else:
print("====不好意思,您不是老板====")
return inner
def test1():
print("====给员工加薪了!====")
def test2():
print("====出新版本,杀一个程序员祭天!====")
#调用iwapper,并传入test1函数的引用,给员工加薪
addMoney = iwapper(test1)
addMoney ()
#调用iwapper,并传入test2函数的引用,杀程序员
killDev = iwapper(test2)
killDev()
打印下结果:
此时,我们产生了两个新函数,一个是addMoney(),另一个是killDev(),调用这两个即实现了添加验证得功能,保持了原来功能函数不用修改,并且大大减少了代码得冗余,但是另一个问题又来了,代码得调用方式变了,我们需要告知其他所有人,修改他们得代码!很显然这是一个更糟糕得做法!
3、路总是一步步走出来得,经历了那么多波折,真相也越来越接近了,聪明得你很快又拿出了下面得方案:
def iwapper(fun):
inner():
if ROLE == "boss":
print("====身法验证通过====")
fun()
else:
print("====不好意思,您不是老板====")
return inner
def test1():
print("====给员工加薪了!====")
def test2():
print("====出新版本,杀一个程序员祭天!====")
#调用iwapper,并传如test1函数的引用,给员工加薪
test1 = iwapper(test1)
test ()
#调用iwapper,并传如test2函数的引用,杀程序员
test2 = iwapper(test2)
test2()
打印下结果:
三、装饰器
1、说了那么多,我们来看看如果遇到上面的需求,如果使用Python装饰器来实现的话会怎么样?看下面代码:
def iwapper(fun):
inner():
if ROLE == "boss":
print("====身法验证通过====")
fun()
else:
print("====不好意思,您不是老板====")
return inner
@iwapper
def test1():
print("====给员工加薪了!====")
@iwapper
def test2():
print("====出新版本,杀一个程序员祭天!====")
那么看下效果:
很明显,效果实现了,这时候也许就又朋友要说道说道了,nmmp,Python解析器那么简单,你前面说那么多废话干嘛,直接一开始就来这段不就行了?朋友莫激动,先把刀放下,其实如果我们单看最后面的代码,我们仅仅知道@iwapper是python装饰器的实现方式而已,但是我们并不知道这句代码到底干了什么事,而我们前面说的就是python解析器的实现原理了!其中得思想获取会对我们有所帮助也不一定呢!