Python 如何理解又晕又好用的装饰器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 如何理解又晕又好用的装饰器相关的知识,希望对你有一定的参考价值。
Python 装饰器这东西对初学者来说是个坑,很容易绕晕,笔者当时初学装饰器时花费了数天时间,看了不同讲师对这块内容的讲解,还是一知半解。
不过装饰器在开发中可是很好用的,有必要攻破,希望这篇文章能帮助学习者快速攻破难关。
初步理解
# 先来看一个简单函数 def show(): print (‘Mr tu‘) show() # 执行结果 : Mr tu # 现在我们用装饰器扩展这个函数,在打印 " Mr tu " 之前打印一行 " hello " def decorate(fun1): def wapper(): print(‘hello‘) fun1() return wapper @decorate def show(): print (‘Mr tu‘) show() # 执行结果 : hello Mr tu # 现在解释上面的代码。 # 1、首先 def decorate(fun1) 定义一个装饰器函数,在此函数里又定义了一个wapper子函数,子函数可以继承父函数的参数。 # 2、 @‘函数名‘是Python的一种语法糖 @decorate 等于 decorate(show) # 还是晕,不明白? 没关系,看下面代码: def decorate(fun1): def wapper(): print(‘hello‘) fun1() return wapper def show(): print (‘Mr tu‘) f1 = decorate(show) f1() # 执行结果 : hello Mr tu # 换成这种写法,执行效果是一样的,因为这就是 @decorate 的本质。 # 就是将被装饰器装饰的函数show作为参数传给装饰器函数。 # 总结执行过程: # 1、show函数作为参数传给装饰器函数 decorate ,那么 fun1 = show # 2、这时执行到装饰器的子函数 wapper,子函数可以继承父函数的参数,所以可以调用 fun1 # 3、然后wapper函数执行 print 打印一行 "hello" , 再然后 调用fun1() —— 这里其实就是执行了show函数。 因为在装饰器一开始执行的时候就把show函数作为参数赋值给了fun1. # 现在明白了吧,只要这里明白,下面的就很好理解了。
装饰带参数的函数
# 一个参数 def decorate(fun1): def wapper(arg1): print(‘hello‘) fun1(arg1) print(‘nice to meet you‘) return wapper @decorate def show(arg1): print (arg1) show(‘Mr Alice‘) # 执行结果: hello Mr Alice nice to meet you # 两个参数 def decorate(fun1): def wapper(arg1,arg2): print(‘hello‘) fun1(arg1,arg2) print(‘nice to meet you‘) return wapper @decorate def show(arg1,arg2): print (arg1,arg2) show(‘Mr Alice‘,‘Mr Tom‘) # 执行结果: hello (‘Mr Alice‘, ‘Mr Tom‘) nice to meet you # n个参数 def decorate(fun1): def wapper(*args,**kwargs): print(‘hello‘) fun1(*args,**kwargs) print(‘nice to meet you‘) return wapper @decorate def show(*args,**kwargs): print (args[0]) print (args[1]) print (args[2]) show(‘Mr Alice‘,‘Mr Tim‘,‘Mr tu‘) # 执行结果: hello Mr Alice Mr Tim Mr tu nice to meet you
一个函数被多个装饰器装饰
def decorate01(fun1): def wapper(*args,**kwargs): print(‘hello world‘) print(‘I am decorate01‘) fun1(*args,**kwargs) return wapper def decorate02(fun1): def wapper(*args,**kwargs): print (‘I am decorate02‘) fun1(*args,**kwargs) print(‘nice to meet you‘) return wapper @decorate01 @decorate02 def show(*args,**kwargs): print (args[0]) print (args[1]) print (args[2]) show(‘Mr Alice‘,‘Mr Tim‘,‘Mr tu‘) # 执行结果: hello world I am decorate01 I am decorate02 Mr Alice Mr Tim Mr tu nice to meet you # 观察print放置的位置不同,对应的输出结果不同。 def decorate01(fun1): def wapper(*args,**kwargs): print(‘hello world‘) fun1(*args,**kwargs) print(‘I am decorate01‘) # 替换到了下面 return wapper def decorate02(fun1): def wapper(*args,**kwargs): print (‘I am decorate02‘) fun1(*args,**kwargs) print(‘nice to meet you‘) return wapper @decorate01 @decorate02 def show(*args,**kwargs): print (args[0]) print (args[1]) print (args[2]) show(‘Mr Alice‘,‘Mr Tim‘,‘Mr tu‘) # 执行结果: hello world I am decorate02 Mr Alice Mr Tim Mr tu nice to meet you I am decorate01
装饰器功能扩展
#!/usr/local/python27/bin/python2.7 def before(request,*args,**kwargs): print(‘before‘) def after(request,*args,**kwargs): print(‘after‘) def Filter(before_func,after_func): def outer(fun1): def wapper(request,*args,**kwargs): before_result = before_func(request,*args,**kwargs) if(before_result != None): return before_result; fun1_result = fun1(request,*args,**kwargs) if(fun1_result != None): return fun1_result; after_result = after_func(request,*args,**kwargs) if(after_result != None): return after_result; return wapper return outer @Filter(before,after) def show(request,*args,**kwargs): print (‘Mr tu‘) show(‘1‘) # 执行结果: before Mr tu after
函数若未定义返回值,执行成功返回值默认为 None ,这里的语句 if (before_result != None) 意思就是before函数执行失败时采取什么操作。
本文出自 “突破舒适区” 博客,请务必保留此出处http://tchuairen.blog.51cto.com/3848118/1843966
以上是关于Python 如何理解又晕又好用的装饰器的主要内容,如果未能解决你的问题,请参考以下文章