Python 装饰器原理剖析
以下内容仅用于帮助个人理解装饰器这个概念,案例可能并不准确。
什么是装饰器?
我们知道iPhone 应用商店中有成千上万的APP,我们也知道苹果系统每年都会大版本更新增加很多新功能。这些功能要想发挥出来需要软件进行适配,如果全部让软件开发者去主动适配,难度很大。苹果要想保持软件的体验,要么强制开发者去适配,要么下架应用,当然如果苹果能在系统底层增加某些功能使得开发者不必亲自进行修改的话那自然是最好了,但我们还是经常看到软件更新说明中写到“适配IOS14”,说明这事需要开发者的参与。但我想,苹果肯定会从“自己在系统层面修改”和“让开发者自己修改”中作出平衡,自己能做的自己做,做不了的由开发者去做。
开放封闭原则
软件设计中有一个“开放封闭原则”,关于开放封闭原则,其核心的思想是:软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。
因此苹果要想增加新的功能,可能不会在系统底层上修改代码,应该是在原来基础上进行功能扩展。
而装饰器的功能就是在不改变原先功能调用的基础上,增加额外功能,就是说开发者不需要自己做出任何改变就能在目前基础上增加新的功能。
因此苹果可能需要一个装饰器。
怎么用装饰器
1 def func1(): 2 print('func1') 3 4 def func1(): 5 print('func2') 6 7 8 func1()
当我执行上述代码的时候,请问会输出什么结果?
答案是:func2
因为程序是自上而下运行的,后面的func1才是最终的func1
有了这个铺垫,我们先看一下装饰器的样子
1 def outer(func): 2 def inner(): 3 print("func_before") 4 r = func() 5 print("func_after") 6 return r 7 return inner 8 9 @outer 10 def func1(): 11 print('func1') 12 13 14 func1()
func_before
func1
func_after
看结果,在不改变原先调用方式的基础上,实现了在原来函数的前后增加功能的效果。
刚才我们说到了,程序自上而下执行,同一个函数,前面的会被后面的“覆盖”。我们要想在原来的功能上增加新功能,又不想改变原来的调用方式,我们就需要重新生成一个同名函数,在这个函数上添加新功能,然后让这个函数“覆盖”原来的函数,就可以实现目的。
我们看上面这段代码,
- 第1行到第7行是一个名叫outer的函数,
- 第9行@outer的作用就是将@outer下面的函数名(即func1)传给outer函数,进而调用outer()
- 进而调用outer()的结果是
- print("func_before")
- 调用func1(),print(func1),返回值None赋值给r(如果原函数有返回值)
- print("func_after")