è£
饰å¨æ¬è´¨ä¸æ¯ä¸ä¸ªPythonå½æ°ï¼å®å¯ä»¥è®©å
¶ä»å½æ°å¨ä¸éè¦åä»»ä½ä»£ç åå¨çåæä¸å¢å é¢å¤åè½ï¼è£
饰å¨çè¿åå¼ä¹æ¯ä¸ä¸ªå½æ°å¯¹è±¡ãå®ç»å¸¸ç¨äºæåé¢éæ±çåºæ¯ï¼æ¯å¦ï¼æå
¥æ¥å¿ãæ§è½æµè¯ãäºå¡å¤çãç¼åãæéæ ¡éªçåºæ¯ãè£
饰å¨æ¯è§£å³è¿ç±»é®é¢çç»ä½³è®¾è®¡ï¼æäºè£
饰å¨ï¼æ们就å¯ä»¥æ½ç¦»åºå¤§éä¸å½æ°åè½æ¬èº«æ å
³çé·å代ç 并继ç»éç¨ãæ¦æ¬ç讲ï¼è£
饰å¨çä½ç¨å°±æ¯ä¸ºå·²ç»åå¨ç对象添å é¢å¤çåè½ã
å
æ¥çä¸ä¸ªç®åä¾åï¼
def foo():
print('i am foo')
ç°å¨æä¸ä¸ªæ°çéæ±ï¼å¸æå¯ä»¥è®°å½ä¸å½æ°çæ§è¡æ¥å¿ï¼äºæ¯å¨ä»£ç ä¸æ·»å æ¥å¿ä»£ç ï¼
def foo():
print('i am foo')
logging.info("foo is running")
bar()ãbar2()ä¹æ类似çéæ±ï¼æä¹åï¼ååä¸ä¸ªloggingå¨barå½æ°éï¼è¿æ ·å°±é æ大éé·åç代ç ï¼ä¸ºäºåå°éå¤å代ç ï¼æ们å¯ä»¥è¿æ ·åï¼éæ°å®ä¹ä¸ä¸ªå½æ°ï¼ä¸é¨å¤çæ¥å¿ ï¼æ¥å¿å¤çå®ä¹ååæ§è¡çæ£çä¸å¡ä»£ç
def use_logging(func):
logging.warn("%s is running" % func.__name__)
func()
def bar():
print('i am bar')
use_logging(bar)
é»è¾ä¸ä¸é¾ç解ï¼
ä½æ¯è¿æ ·çè¯ï¼æ们æ¯æ¬¡é½è¦å°ä¸ä¸ªå½æ°ä½ä¸ºåæ°ä¼ éç»use_loggingå½æ°ãèä¸è¿ç§æ¹å¼å·²ç»ç ´åäºåæç代ç é»è¾ç»æï¼ä¹åæ§è¡ä¸å¡é»è¾æ¶ï¼æ§è¡è¿è¡bar()ï¼ä½æ¯ç°å¨ä¸å¾ä¸æ¹æuse_logging(bar)ãé£ä¹æ没ææ´å¥½çæ¹å¼çå¢ï¼å½ç¶æï¼çæ¡å°±æ¯è£
饰å¨ã
ç®åè£
饰å¨
def use_logging(func):
def wrapper(*args, **kwargs):
logging.warn("%s is running" % func.__name__)
return func(*args, **kwargs)
return wrapper
def bar():
print('i am bar')
bar = use_logging(bar)
bar()
å½æ°use_loggingå°±æ¯è£
饰å¨ï¼å®ææ§è¡çæ£ä¸å¡æ¹æ³çfuncå
裹å¨å½æ°éé¢ï¼çèµ·æ¥åbar被use_loggingè£
饰äºãå¨è¿ä¸ªä¾åä¸ï¼å½æ°è¿å
¥åéåºæ¶
ï¼è¢«ç§°ä¸ºä¸ä¸ªæ¨ªåé¢(Aspect)ï¼è¿ç§ç¼ç¨æ¹å¼è¢«ç§°ä¸ºé¢ååé¢çç¼ç¨(Aspect-Oriented Programming)ã
@符å·æ¯è£
饰å¨çè¯æ³ç³ï¼å¨å®ä¹å½æ°çæ¶å使ç¨ï¼é¿å
åä¸æ¬¡èµå¼æä½
def use_logging(func):
def wrapper(*args, **kwargs):
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper
@use_logging
def foo():
print("i am foo")
@use_logging
def bar():
print("i am bar")
bar()
å¦ä¸æ示ï¼è¿æ ·æ们就å¯ä»¥çå»bar =
use_logging(bar)è¿ä¸å¥äºï¼ç´æ¥è°ç¨bar()å³å¯å¾å°æ³è¦çç»æãå¦ææ们æå
¶ä»ç类似å½æ°ï¼æ们å¯ä»¥ç»§ç»è°ç¨è£
饰å¨æ¥ä¿®é¥°å½æ°ï¼èä¸ç¨éå¤ä¿®æ¹å½æ°æè
å¢å æ°çå°è£
ãè¿æ ·ï¼æ们就æé«äºç¨åºçå¯éå¤å©ç¨æ§ï¼å¹¶å¢å äºç¨åºçå¯è¯»æ§ã
è£
饰å¨å¨Python使ç¨å¦æ¤æ¹ä¾¿é½è¦å½å äºPythonçå½æ°è½åæ®éç对象ä¸æ ·è½ä½ä¸ºåæ°ä¼ éç»å
¶ä»å½æ°ï¼å¯ä»¥è¢«èµå¼ç»å
¶ä»åéï¼å¯ä»¥ä½ä¸ºè¿åå¼ï¼å¯ä»¥è¢«å®ä¹å¨å¦å¤ä¸ä¸ªå½æ°å
ã
带åæ°çè£
饰å¨
è£
饰å¨è¿ææ´å¤§ççµæ´»æ§ï¼ä¾å¦å¸¦åæ°çè£
饰å¨ï¼å¨ä¸é¢çè£
饰å¨è°ç¨ä¸ï¼æ¯å¦@use_loggingï¼è¯¥è£
饰å¨å¯ä¸çåæ°å°±æ¯æ§è¡ä¸å¡çå½æ°ãè£
饰å¨çè¯æ³å
许æ们å¨è°ç¨æ¶ï¼æä¾å
¶å®åæ°ï¼æ¯å¦@decorator(a)ãè¿æ ·ï¼å°±ä¸ºè£
饰å¨çç¼åå使ç¨æä¾äºæ´å¤§ççµæ´»æ§ã
def use_logging(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == "warn":
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper
return decorator
@use_logging(level="warn")
def foo(name='foo'):
print("i am %s" % name)
foo()
ä¸é¢çuse_loggingæ¯å
许带åæ°çè£
饰å¨ãå®å®é
ä¸æ¯å¯¹åæè£
饰å¨çä¸ä¸ªå½æ°å°è£
ï¼å¹¶è¿åä¸ä¸ªè£
饰å¨ãæ们å¯ä»¥å°å®ç解为ä¸ä¸ªå«æåæ°çéå
ãå½æ
们使ç¨@use_logging(level="warn")è°ç¨çæ¶åï¼Pythonè½å¤åç°è¿ä¸å±çå°è£
ï¼å¹¶æåæ°ä¼ éå°è£
饰å¨çç¯å¢ä¸ã
ç±»è£
饰å¨
åæ¥ççç±»è£
饰å¨ï¼ç¸æ¯å½æ°è£
饰å¨ï¼ç±»è£
饰å¨å
·æçµæ´»åº¦å¤§ãé«å
èãå°è£
æ§çä¼ç¹ã使ç¨ç±»è£
饰å¨è¿å¯ä»¥ä¾é ç±»å
é¨ç\_\_call\_\_æ¹æ³ï¼å½ä½¿ç¨ @ å½¢å¼å°è£
饰å¨éå å°å½æ°ä¸æ¶ï¼å°±ä¼è°ç¨æ¤æ¹æ³ã
class Foo(object):
def __init__(self, func):
self._func = func
def __call__(self):
print ('class decorator runing')
self._func()
print ('class decorator ending')
@Foo
def bar():
print ('bar')
bar()
functools.wraps
使ç¨è£
饰å¨æ大å°å¤ç¨äºä»£ç ï¼ä½æ¯ä»æä¸ä¸ªç¼ºç¹å°±æ¯åå½æ°çå
ä¿¡æ¯ä¸è§äºï¼æ¯å¦å½æ°çdocstringã__name__ãåæ°å表ï¼å
çä¾åï¼
è£
饰å¨
def logged(func):
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging
å½æ°
@logged
def f(x):
"""does some math"""
return x + x * x
该å½æ°å®æçä»·äºï¼
def f(x):
"""does some math"""
return x + x * x
f = logged(f)
ä¸é¾åç°ï¼å½æ°f被with_loggingå代äºï¼å½ç¶å®çdocstringï¼__name__å°±æ¯åæäºwith_loggingå½æ°çä¿¡æ¯äºã
print f.__name__ # prints 'with_logging'
print f.__doc__ # prints None
è¿ä¸ªé®é¢å°±æ¯è¾ä¸¥éçï¼å¥½å¨æ们æfunctools.wrapsï¼wrapsæ¬èº«ä¹æ¯ä¸ä¸ªè£
饰å¨ï¼å®è½æåå½æ°çå
ä¿¡æ¯æ·è´å°è£
饰å¨å½æ°ä¸ï¼è¿ä½¿å¾è£
饰å¨å½æ°ä¹æååå½æ°ä¸æ ·çå
ä¿¡æ¯äºã
from functools import wraps
def logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging
@logged
def f(x):
"""does some math"""
return x + x * x
print f.__name__ # prints 'f'
print f.__doc__ # prints 'does some math'
å
ç½®è£
饰å¨
@staticmathodã@classmethodã@property
è£
饰å¨ç顺åº
@a
@b
@c
def f ():
çæäº
f = a(b(c(f)))
温馨提示:答案为网友推荐,仅供参考