使用多個修飾器的話:
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')
我們調(diào)用c('c')的時候會先調(diào)用b(c),b(c)打印字符"b"然后返回c,然后再調(diào)用a(c),a(c)打印字符"a",然后返回方法d,然后再執(zhí)行d('c'),打印cd。
先調(diào)用堆棧里的修飾器里面的函數(shù)然后執(zhí)行顯式的函數(shù)
后續(xù)補充:
雙層嵌套:
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():
相當于執(zhí)行了語句:
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) 保留原有的函數(shù)簽名
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper