Python学习笔记 装饰器详解

Python装饰器详解:

装饰器的作用无疑是在函数执行的前后添加额外的内容,以满足我们需要的需求,例如日志处理,性能测试,事物处理等。

1:最简单的实现前后添加类容的需求:

 
   
#!/usr/bin/python
#-*-coding:utf-8-*-
#deco1.py
 
def deco(func):
print 'before'
func()
print 'after'
 
def myfunc():
print 'myfunc'
 
myfunc=deco(myfunc)
 
    
before
myfunc
after

无疑这样的方式不易于进行扩展以及维护 因为它为了需求改动了我原来的代码 原来应该只是  func() 这一个调用,于是装饰器模式就出现了
2:极少改动的源代码的装饰器:
 
    
#!/usr/bin/python
#-*-coding:utf-8-*-
#deco2.py
 
def deco(func):
def wrapper():
print 'before'
func()
print 'after'
return wrapper
 
 
def myfunc():
print 'myfunc'
 
myfunc=deco(myfunc)
myfunc()
print myfunc.__name__
 
     
before
myfunc
after
wrapper

3:使用语法糖@来装饰函数 .
 
    
#!/usr/bin/python
#-*-coding:utf-8-*-
#deco3.py
 
def deco(func):
def wrapper():
print 'before'
func()
print 'after'
return wrapper
 
@deco
def myfunc():
print 'myfunc'
 
myfunc()
 
print myfunc.__name__
 
     
before
myfunc
after
wrapper

无疑可以看出来 @deco 相当于执行了命令 myfunc=deco(myfunc) 这一个命令,同时它也就只是这样而已

4:带有参数的高阶装饰器:

 
     
#!/usr/bin/python
#-*-coding:utf-8-*-
#deco4.py
 
def outer(text):
def deco(func):
def wrapper(*args,**kw):
print 'before'
print text
func(*args,**kw)
print 'after'
return wrapper
return deco
 
@outer('hello outer')
def myfunc(name):
print 'myfunc',name
 
myfunc('licheng')
 
print myfunc.__name__
 
      
before
hello outer
myfunc licheng
after
wrapper

无疑语法糖加上参数也只是在外围包上了一层函数和返回值而已。 @outer('hello outer')相当于 myfunc=outer('hello outer')(myfunc)

5:解决函数名的问题

上述装饰器基本已经可以说完整了 但是依旧存在一个问题,那就是我们可以看到经过装饰后,myfunc的函数名变成了wrapper.显然这对于一些依赖于函数名的反射机制会发生异常错误等。因此我们需要将 myfunc.__name__ =myfunc 实现

而这只需要一句话  @functools.wraps(func)就可以实现。

 
      
#!/usr/bin/python
#-*-coding:utf-8-*-
#deco4.py
import functools
def outer(text):
def deco(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print 'before'
print text
func(*args,**kw)
print 'after'
return wrapper
return deco
 
@outer('hello outer')
def myfunc(name):
print 'myfunc',name
 
myfunc('licheng')
 
print myfunc.__name__
 
       
before
hello outer
myfunc licheng
after
myfunc

这个装饰器 @functools.wraps(func) 是functools的一个特殊的装饰器,相当于 wrapper=functools.wraps(func)(wrapper)






你可能感兴趣的:(python)