人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

Python語(yǔ)法詳解之decorator裝飾器

發(fā)布日期:2021-12-22 00:25 | 文章來(lái)源:站長(zhǎng)之家

python 是一門(mén)優(yōu)雅的語(yǔ)言,有些使用方法就像魔法一樣。裝飾器(decorator)就是一種化腐朽性為神奇的技巧。最近一直都在使用 Tornado 框架,一直還是念念不忘 Flask 。Flask 是我最喜歡的 Python 框架,最早被它吸引也是源自它使用裝飾器這個(gè)語(yǔ)法糖(Syntactic sugar)來(lái)做 Router,讓代碼看上去就感覺(jué)甜甜的。

Tornado 中的 Router 略顯平淡,懷念 Flask 的味道,于是很好奇的想知道 Flask 是如何使用這個(gè)魔法。通過(guò)閱讀 Flask 的源碼,我們也可以為 Tornado 實(shí)現(xiàn)了一個(gè)裝飾器 Router。

當(dāng)然對(duì)于剛接觸 Python 的人,也許很容易理解裝飾器本質(zhì)是設(shè)計(jì)模式中的裝飾器模式。可是 Python 通過(guò)@一個(gè)實(shí)現(xiàn)裝飾器的語(yǔ)法糖。下面看下Python語(yǔ)法詳解之decorator裝飾器。

一、定義

裝飾器 decorator 或者稱(chēng)為包裝器,是對(duì)函數(shù)的一種包裝。

二、作用

它能使函數(shù)的功能得到擴(kuò)充,而同時(shí)不用修改函數(shù)本身的代碼。它能夠增加函數(shù)執(zhí)行前、執(zhí)行后的行為,而不需對(duì)調(diào)用函數(shù)的代碼做任何改變。

三、舉例

初始化函數(shù)

# 函數(shù)hello,輸出 hello + name 的字符串 
def hello(name):
 return 'hello ' + name  

希望實(shí)現(xiàn)功能:在每一個(gè)調(diào)用 hello 函數(shù)的時(shí)候,將輸出的字符串用 <tag>包住

例如:hello john 變成 <tag>hello john<tag>

方法一:自定義wrapper函數(shù)

這種方法成功修改了函數(shù) hello 的行為,不過(guò)需要修改對(duì) hello的調(diào)用。

每一個(gè)調(diào)用hello 的地方,都要給成調(diào)用wrapper,并修改參數(shù)列表

def hello(name):
 return 'hello ' + name
 
def wrapper(tag, func, *arg, **kvargs):
 tag = "<" + tag + ">"
 return tag + func(*arg, **kvargs) + tag
 
if __name__ == "__main__":
 print(wrapper('p', hello, 'john'))

輸出

方法二:自定義decorator函數(shù)

為了不改變對(duì) hello的調(diào)用。我們需要得到一個(gè)新的函數(shù)對(duì)象,它修改 hello的行為,并用這個(gè)對(duì)象對(duì) hello賦值。

從而調(diào)用 hello的時(shí)候,調(diào)用的是擴(kuò)充行為后的 hello

def hello(name):
 return 'hello ' + name
def myDecorator(func, tag):
 def myWrapper(*arg, **kvargs):  # 重新包裝func,其參數(shù)列表與func一致
  sign = "<" + tag + ">"
  return sign + func(*arg, **kvargs) + sign
 
 return myWrapper
 
hello = myDecorator(hello, "div")  # 用新的函數(shù)對(duì)象修改hello
 
if __name__ == "__main__":
 print(hello("john")) 

這樣,只要hello被myDecorator 賦值一次,以后再調(diào)用hello 時(shí),就調(diào)用的是包裝后的函數(shù)

輸出

方法三:python的decorator

python 的裝飾器所做的事與方式2類(lèi)似

它通過(guò)語(yǔ)法糖使裝飾器看起來(lái)更清晰、簡(jiǎn)介,而不用每次都書(shū)寫(xiě)方式2中第7行代碼 hello = myDecorator(hello, "div")

def setTag(tag):  # 由于此裝飾器需要參數(shù),所以要再套一層
 def myDecorator(func):  # 裝飾器的核心,接受函數(shù)對(duì)象做參數(shù),返回包裝后的函數(shù)對(duì)象
  def myWrapper(*arg, **kvargs):  # 包裝的具體過(guò)程
sign = "<" + tag + ">"
return sign + func(*arg, **kvargs) + sign
 
  return myWrapper
 
 return myDecorator
 
 
@setTag("div")  # 用@標(biāo)簽在定義函數(shù)時(shí)套上裝飾器
def hello(name):
 return 'hello' + name
 
 
if __name__ == '__main__':
 print(hello('john'))

本質(zhì)上,方式2 與 方式3 完成的是同一件事,只不過(guò)方式3 比方式2 代碼更簡(jiǎn)潔,方便。

比如,現(xiàn)在要給 hello 函數(shù)套上三個(gè)標(biāo)簽<body><div><p>

如果用方式2

hello = myDecorator(myDecorator(myDecorator(hello, "body"),"div"),"p")

如果用方式3

@myDecorator("body")
@myDecorator("div")
@myDecorator("p")
def hello(name)
 return 'hello' + name

在多個(gè)裝飾器嵌套的情況下,python內(nèi)置的decorator 結(jié)構(gòu)更清晰。

偽代碼:

def myDecorator(...):    #定義裝飾器,可能帶參數(shù)
 def decorator(func): #裝飾器核心,以被裝飾的函數(shù)對(duì)象為參數(shù),返回裝飾后的函數(shù)對(duì)象
  def wrapper(*args, **kvargs): #裝飾的過(guò)程,參數(shù)列表適應(yīng)不同參數(shù)的函數(shù)
 ... #修改函數(shù)調(diào)用前的行為
 func(*args, **kvargs) #調(diào)用函數(shù)
 ... #修改函數(shù)調(diào)用后的行為
return wrapper
  return decorator
 
@myDecorator(...):    #給函數(shù)加上裝飾器
def myFunc(...):      #自己定義的功能函數(shù)
 ...

知識(shí)點(diǎn):

  • 在python中,當(dāng)*和**符號(hào)出現(xiàn)在函數(shù)定義的參數(shù)中時(shí),表示任意數(shù)目參數(shù)收集。*arg表示任意多個(gè)無(wú)名參數(shù),類(lèi)型為tuple;**kwargs表示關(guān)鍵字參數(shù),為dict,使用時(shí)需將*arg放在**kwargs之前,否則會(huì)有“SyntaxError: non-keyword arg after keyword arg”的語(yǔ)法錯(cuò)誤
  • 在函數(shù)調(diào)用時(shí),*會(huì)以單個(gè)元素的形式解包一個(gè)元祖,使其成為獨(dú)立的參數(shù)。
  • 在函數(shù)調(diào)用時(shí),**會(huì)以鍵/值對(duì)的形式解包一個(gè)字典,使其成為獨(dú)立的關(guān)鍵字參數(shù)。

到此這篇關(guān)于Python語(yǔ)法:decorator裝飾器的文章就介紹到這了,更多相關(guān)Python decorator裝飾器內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線(xiàn)路精選!

全天候客戶(hù)服務(wù)

7x24全年不間斷在線(xiàn)

專(zhuān)屬顧問(wèn)服務(wù)

1對(duì)1客戶(hù)咨詢(xún)顧問(wèn)

在線(xiàn)
客服

在線(xiàn)客服:7*24小時(shí)在線(xiàn)

客服
熱線(xiàn)

400-630-3752
7*24小時(shí)客服服務(wù)熱線(xiàn)

關(guān)注
微信

關(guān)注官方微信
頂部