今天的参考文章来自【测试开发坑货】(作者米洛,人称 Woody 哥/无敌卷魔/测开届的肝帝等等),继续学习 python 的装饰器语法基础。目标就是彻底地理解它,学会它。一次不行就一百次,读过《笨办法学 python》的同学都知道,看十遍也不如照着敲一遍来的印象深,更何况我这个水平的菜鸟。所以,千万别犯懒,一字一句,照着敲起来,这次我们调皮一点:
def simple(func):
def wrapper():
print("无敌哥开始卷了")
func()
print("无敌哥卷完了")
return wrapper
@simple
def func():
print("无敌哥正在卷ing")
def func1():
print("没有@wrapper无敌哥也在卷")
if __name__ == "__main__":
func()
print("----分割线----")
simple(func1)()
print("----分割线----")
f = simple(func1)
f()
这个例子,无敌哥进行了非常详细的讲解。将@wrapper这个比较抽象的语法,拆解为了 simple(func1)() 这种形式,如果还不理解,就干脆再拆一步,变成 f=simple(func1) 和 f(),这下连我都看懂了,想必各位也一定明白了:
simple(func1) 返回了 wrapper 这个对象,这个对象本身又是一个函数,赋给 f 这个变量,f() 则执行了返回的 f 方法,所以合并到一起就是 simple(func)(),这样拆出来就更好理解了。所以装饰器的本质就是一个 function 而已,只不过 @ 的写法会便捷很多。不要再认为装饰器是什么很高深的写法了,其实理解下来就是个函数套娃的操作。
执行结果如下:
无敌哥开始卷了
无敌哥正在卷ing
无敌哥卷完了
----分割线----
无敌哥开始卷了
没有@wrapper无敌哥也在卷
无敌哥卷完了
----分割线----
无敌哥开始卷了
没有@wrapper无敌哥也在卷
无敌哥卷完了
接下来无敌哥进一步讲解了装饰器的用法:带参数的装饰器。有了上面的基础概念,这次理解容易多了,还是要亲手敲出来才比较有感觉:
def simple(func):
def wrapper(*args,**kwargs):
print("无敌哥又开始卷了")
func(*args,**kwargs)
print("无敌哥又卷完了")
return wrapper
@simple
def func(a,b,key="无敌哥流批"):
print(a,b,key)
print("无敌哥正在卷ing")
if __name__ == "__main__":
func(['饭佬',666],{'汤总':'9分女管理'})
运行一下可以看到,和上面相比,多出了一些参数功能,args,*kwargs 有啥区别这里就不赘述了,一个列表一个字典,至于为啥它俩一前一后固定这样,有面试官会问,别问,问就是语法就这么规定的,你不按套路出牌他就给你报错。
无敌哥又开始卷了
['饭佬', 666] {'汤总': '9分女管理'} 无敌哥流批
无敌哥正在卷ing
无敌哥又卷完了
用这个写法还有一个好处就是灵活,参数有多个的话就处理成列表或者字典形式,都能接收,避免了由于参数变化导致的报错.
我想要一个循环执行 N 次方法的装饰器,命名为 loop,如果@loop形式,则不进行循环,如果是@loop(5),则要循环方法 5 次,你可以试试吗?
@loop
def func1():
"无敌哥卷起来了"
@loop(5)
def func2():
"无敌哥卷了5次"
试试就试试:
完,学废了,欲知后事如何,且看下回分解,强悍的无敌哥,一个装饰品能写 3 篇大论,真乃神人也。