裝飾器

from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated

@decorator_name
def func():
    return "Function is running"

can_run = True
print(func())

can_run = Flase
print(func())
注意:@wraps接受?個(gè)函數(shù)來(lái)進(jìn)?裝飾牢贸,并加?了復(fù)制函數(shù)名稱塘装、注釋?檔险毁、參數(shù)列表 等等的功能疾忍。這可以讓我們?cè)谘b飾器??訪問(wèn)在裝飾之前的函數(shù)的屬性。


使?場(chǎng)景

授權(quán)(Authorization)

裝飾器能有助于檢查某個(gè)?是否被授權(quán)去使??個(gè)web應(yīng)?的端點(diǎn)(endpoint)黑竞。它們被?量

使?于Flask和Django web框架中眨层。這?是?個(gè)例?來(lái)使?基于裝飾器的授權(quán):

from functools improt wraps

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            authenticate()
        return f(*args, **kwargs)
    return decorated

?志(Logging)

?志是裝飾器運(yùn)?的另?個(gè)亮點(diǎn)。這是個(gè)例?:

from functools import wraps

def logit(func):
    @wraps(func):
        def with_logging(*args, **kwargs):
            print(func.__name__ + " was called")
            return func(*args, **kwargs)
        return with_logging
@logit
def addition_func(x):
    """Do some math."""
    return x + x
return = addition_func(4)

在函數(shù)中嵌?裝飾器

我們回到?志的例?面哥,并創(chuàng)建?個(gè)包裹函數(shù)哎壳,能讓我們指定?個(gè)?于輸出的?志?件。

from functools import wraps
def logit(logfile='out.log'):
    def logging_decorator(func):
        @wraps(func)
        def wrapped_function(func):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打開(kāi)logfile尚卫,并寫(xiě)入內(nèi)容
            with open(logfile, 'a') as open_file:
                # 現(xiàn)在將日志打到指定的logfile
                opened_file.write(log_string + '\n')
        return wrapped_function
    return logging_decorator

@logit()
def myfuncl():
    pass
myfunc1() 
# Output: myfunc1 was called 
# 現(xiàn)在?個(gè)叫做 out.log 的?件出現(xiàn)了归榕,??的內(nèi)容就是上?的字符串 @logit(logfile='func2.log') 
def myfunc2(): 
    pass 
myfunc2(): 
    pass 
myfunc2() 
# Output: myfunc2 was called 
# 現(xiàn)在?個(gè)叫做 func2.log 的?件出現(xiàn)了,??的內(nèi)容就是上?的字符串

裝飾器類

現(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题山。

class logit(object): 
    def __init__(self, logfile='out.log'):
        self.logfile = logfile 
    def __call__(self, func): 
        log_string = func.__name__ + " was called" 
        print(log_string) 
        # 打開(kāi)logfile并寫(xiě)? 
        with open(self.logfile, 'a') as opened_file: 
        # 現(xiàn)在將?志打到指定的?件 
            opened_file.write(log_string + '\n') 
            # 現(xiàn)在兰粉,發(fā)送?個(gè)通知 
            self.notify() 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(logit, self).__init__(*args, **kwargs) 
    def notify(self): 
        # 發(fā)送?封email到self.email Python進(jìn)階
        # 這?就不做實(shí)現(xiàn)了 
        pass

從現(xiàn)在起,@email_logit將會(huì)和@logit產(chǎn)?同樣的效果闪彼,但是在打?志的基礎(chǔ)上甜孤,還

會(huì)多發(fā)送?封郵件給管理員。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末畏腕,一起剝皮案震驚了整個(gè)濱河市缴川,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌描馅,老刑警劉巖把夸,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異铭污,居然都是意外死亡恋日,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嘹狞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)岂膳,“玉大人,你說(shuō)我怎么就攤上這事刁绒∶朴” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵知市,是天一觀的道長(zhǎng)傻盟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)嫂丙,這世上最難降的妖魔是什么娘赴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮跟啤,結(jié)果婚禮上诽表,老公的妹妹穿的比我還像新娘。我一直安慰自己隅肥,他們只是感情好竿奏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著腥放,像睡著了一般泛啸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秃症,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天候址,我揣著相機(jī)與錄音吕粹,去河邊找鬼。 笑死岗仑,一個(gè)胖子當(dāng)著我的面吹牛匹耕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荠雕,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼稳其,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了舞虱?” 一聲冷哼從身側(cè)響起欢际,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎矾兜,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體患久,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椅寺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒋失。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片返帕。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖篙挽,靈堂內(nèi)的尸體忽然破棺而出荆萤,到底是詐尸還是另有隱情,我是刑警寧澤铣卡,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布链韭,位于F島的核電站,受9級(jí)特大地震影響煮落,放射性物質(zhì)發(fā)生泄漏敞峭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一蝉仇、第九天 我趴在偏房一處隱蔽的房頂上張望旋讹。 院中可真熱鬧,春花似錦轿衔、人聲如沸沉迹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鞭呕。三九已至,卻和暖如春裙秋,著一層夾襖步出監(jiān)牢的瞬間琅拌,已是汗流浹背缨伊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留进宝,地道東北人刻坊。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像党晋,于是被迫代替她去往敵國(guó)和親谭胚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容