現(xiàn)在我們有了能用于正式環(huán)境的logit
裝飾器,但當(dāng)我們的應(yīng)用的某些部分還比較脆弱時(shí),異常也許是需要更緊急關(guān)注的事情。比方說(shuō)有時(shí)你只想打日志到一個(gè)文件。而有時(shí)你想把引起你注意的問(wèn)題發(fā)送到一個(gè)email,同時(shí)也保留日志,留個(gè)記錄。這是一個(gè)使用繼承的場(chǎng)景,但目前為止我們只看到過(guò)用來(lái)構(gòu)建裝飾器的函數(shù)。
幸運(yùn)的是,類也可以用來(lái)構(gòu)建裝飾器。那我們現(xiàn)在以一個(gè)類而不是一個(gè)函數(shù)的方式,來(lái)重新構(gòu)建logit
。
from functools import wraps
class logit(object):
def __init__(self, logfile='out.log'):
self.logfile = logfile
def __call__(self, func):
@wraps(func)
def wrapped_function(*args, **kwargs):
log_string = func.__name__ + " was called"
print(log_string)
# 打開(kāi)logfile并寫入
with open(self.logfile, 'a') as opened_file:
# 現(xiàn)在將日志打到指定的文件
opened_file.write(log_string + '\n')
# 現(xiàn)在,發(fā)送一個(gè)通知
self.notify()
return func(*args, **kwargs)
return wrapped_function
def notify(self):
# logit只打日志,不做別的
pass
這個(gè)實(shí)現(xiàn)有一個(gè)附加優(yōu)勢(shì),在于比嵌套函數(shù)的方式更加整潔,而且包裹一個(gè)函數(shù)還是使用跟以前一樣的語(yǔ)法:
@logit()
def myfunc1():
pass
現(xiàn)在,我們給logit
創(chuàng)建子類,來(lái)添加email的功能(雖然email這個(gè)話題不會(huì)在這里展開(kāi))。
class email_logit(logit):
'''
一個(gè)logit的實(shí)現(xiàn)版本,可以在函數(shù)調(diào)用時(shí)發(fā)送email給管理員
'''
def __init__(self, email='admin@myproject.com', *args, **kwargs):
self.email = email
super(email_logit, self).__init__(*args, **kwargs)
def notify(self):
# 發(fā)送一封email到self.email
# 這里就不做實(shí)現(xiàn)了
pass
從現(xiàn)在起,@email_logit
將會(huì)和@logit
產(chǎn)生同樣的效果,但是在打日志的基礎(chǔ)上,還會(huì)多發(fā)送一封郵件給管理員。