免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Python進(jìn)階系列(五)

裝飾器

使用場景

現(xiàn)在我們來看一下裝飾器在哪些地方特別耀眼,以及使用它可以讓一些事情管理起來變得更簡單。

授權(quán)(Authorization)

裝飾器能有助于檢查某個人是否被授權(quán)去使用一個web應(yīng)用的端點(endpoint)。它們被大量

使用于Flask和Django web框架中。這里是一個例子來使用基于裝飾器的授權(quán):

from functools import 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)

日志是裝飾器運用的另一個亮點。這是個例子:

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



result = addition_func(4)

# Output: addition_func was called

我敢肯定你已經(jīng)在思考裝飾器的一個其他聰明用法了。

帶參數(shù)的裝飾器

來想想這個問題,難道@wraps不也是個裝飾器嗎?但是,它接收一個參數(shù),就像任何普通的函數(shù)能做的那樣。那么,為什么我們不也那樣做呢?

這是因為,當(dāng)你使用@my_decorator語法時,你是在應(yīng)用一個以單個函數(shù)作為參數(shù)的一個包裹函數(shù)。記住,Python里每個東西都是一個對象,而且這包括函數(shù)!記住了這些,我們可以編寫一下能返回一個包裹函數(shù)的函數(shù)。

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

我們回到日志的例子,并創(chuàng)建一個包裹函數(shù),能讓我們指定一個用于輸出的日志文件。

from functools import wraps

def logit(logfile='out.log'):

??? def logging_decorator(func):

??????? @wraps(func)

??????? def wrapped_function(*args, **kwargs):

??????????? log_string = func.__name__ + " was called"

? ??????????print(log_string)

??????????? # 打開logfile,并寫入內(nèi)容

??????????? with open(logfile, 'a') as opened_file:

??????????????? # 現(xiàn)在將日志打到指定的logfile

??????????????? opened_file.write(log_string + '\n')

??????????? return func(*args, **kwargs)

??????? return wrapped_function

??? return logging_decorator



@logit()

def myfunc1():

??? pass



myfunc1()

# Output: myfunc1 was called

# 現(xiàn)在一個叫做 out.log 的文件出現(xiàn)了,里面的內(nèi)容就是上面的字符串



@logit(logfile='func2.log')

def myfunc2():

??? pass

myfunc2()

# Output: myfunc2 was called

# 現(xiàn)在一個叫做 func2.log 的文件出現(xiàn)了,里面的內(nèi)容就是上面的字符串

裝飾器類

現(xiàn)在我們有了能用于正式環(huán)境的logit裝飾器,但當(dāng)我們的應(yīng)用的某些部分還比較脆弱時,異常也許是需要更緊急關(guān)注的事情。比方說有時你只想打日志到一個文件。而有時你想把引起你注意的問題發(fā)送到一個email,同時也保留日志,留個記錄。這是一個使用繼承的場景,但目前為止我們只看到過用來構(gòu)建裝飾器的函數(shù)。

幸運的是,類也可以用來構(gòu)建裝飾器。那我們現(xiàn)在以一個類而不是一個函數(shù)的方式,來重新構(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)

??????????? # 打開logfile并寫入

??????????? with open(self.logfile, 'a') as opened_file:

??????????????? # 現(xiàn)在將日志打到指定的文件

??????????????? opened_file.write(log_string + '\n')

??????????? # 現(xiàn)在,發(fā)送一個通知

??????????? self.notify()

??????????? return func(*args, **kwargs)

??????? return wrapped_function


??? def notify(self):

??????? # logit只打日志,不做別的

??????? pass

這個實現(xiàn)有一個附加優(yōu)勢,在于比嵌套函數(shù)的方式更加整潔,而且包裹一個函數(shù)還是使用跟以前一樣的語法:

@logit()

def myfunc1():

??? pass

現(xiàn)在,我們給logit創(chuàng)建子類,來添加email的功能(雖然email這個話題不會在這里展開)。

class email_logit(logit):
??? 一個logit的實現(xiàn)版本,可以在函數(shù)調(diào)用時發(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

??????? # 這里就不做實現(xiàn)了

??????? pass

從現(xiàn)在起,@email_logit將會和@logit產(chǎn)生同樣的效果,但是在打日志的基礎(chǔ)上,還會多發(fā)送一封郵件給管理員。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python 函數(shù)裝飾器 | 菜鳥教程
Python函數(shù)進(jìn)階:探索高級函數(shù)特性與技巧
python中的組包與解包
Python入門很難?別擔(dān)心,找對方法!函數(shù)基礎(chǔ)知識送給你們
從零開始學(xué)Python:21課-函數(shù)的高級應(yīng)用
《源碼探秘 CPython》57. 函數(shù)是怎么創(chuàng)建的?
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服