使用多个修饰器的话:
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