装饰器@


使用多个修饰器的话:

1.  #!/usr/bin/env python  
2.    
3.  def a(fn):  
4.      print 'a'  
5.      def d(st):  
6.          print st+'d'  
7.      return d  
8.    
9.  def b(fn):  
10.     print 'b'  
11.     return fn  
12.  
13. @a  
14. @b  
15. def c(st):  
16.     print st  
17.       
18. c('c')  

我们调用c('c')的时候会先调用b(c),b(c)打印字符"b"然后返回c,然后再调用a(c),a(c)打印字符"a",然后返回方法d,然后再执行d('c'),打印cd。
先调用堆栈里的修饰器里面的函数然后执行显式的函数


后续补充:

双层嵌套:
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

@log
def now():
    print('2015-3-25')

>>> now()
call now():
2015-3-25

@log def now():
相当于执行了语句:
now = log(now)

三层嵌套:
def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('execute')
def now():
    print('2015-3-25')

>>> now()
execute now():
2015-3-25

@log('execute')
def now():
相当于 now = log('execute')(now)


Decorator 还可以为类增加额外的成员:
def hello(cls):
     cls.hello = staticmethod(lambda: "HELLO")
     return cls
@hello
class World(object):pass

>>>World.hello( )
'HELLO'

functools.wraps

在使用 Decorator 的过程中,难免会损失一些原本的功能信息

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

@log('execute')
def now():
    print('2015-3-25')

>>> now.__name__
'wrapper'                 // 原本应该是now的

-----------------------------------------
加入 @functools.wraps(func) 保留原有的函数签名
def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容