日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Python 裝飾器學(xué)習(xí)以及實(shí)際使用場(chǎng)景實(shí)踐

前言

從化ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

前幾天在看Flask框架,,不是非常的理解,回來(lái)補(bǔ)裝飾器的功課。閱讀很多的關(guān)于裝飾器的文章,自己整理一下,適合自己的思路的方法和例子,與大家分享。

  
 
  1. app = Flask(__name__) 
  2. @app.route("/") 
  3. def hello(): 
  4. return "Hello World!" 

1、裝飾器是什么

裝飾器是Python語(yǔ)言中的高級(jí)語(yǔ)法。主要的功能是對(duì)一個(gè)函數(shù)、方法、或者類進(jìn)行加工,作用是為已經(jīng)存在的對(duì)象添加額外的功能,提升代碼的可讀性。
裝飾器是設(shè)計(jì)模式的一種,被用于有切面需求的場(chǎng)景,較為經(jīng)典的有插入日志、性能測(cè)試、事務(wù)處理等

2、裝飾器的語(yǔ)法

裝飾器的語(yǔ)法如下:

當(dāng)前Python的裝飾器語(yǔ)法如下:

  
 
  1. @dec2 
  2. @dec1 
  3. def func(arg1, arg2, ...): 
  4.     .... 
  5.     return funx 
  6.  
  7. 上面的代碼相當(dāng)于: 
  8.  
  9. def func(arg1, arg2, ...): 
  10.     pass 
  11. func = dec2(dec1(func)) 

裝飾器可以用def的形式來(lái)定義。裝飾器接收一個(gè)可調(diào)用對(duì)象作為輸入?yún)?shù),并返回一個(gè)新的可調(diào)用對(duì)象。
裝飾器新建了一個(gè)可調(diào)用對(duì)象,也就是return 返回的函數(shù)funx,在新增的函數(shù)中,可以添加我們需要的功能,并通過(guò)調(diào)用原有函數(shù)來(lái)實(shí)現(xiàn)原有函數(shù)的功能。

3、裝飾器的使用

3.1不帶參數(shù)的裝飾器

定義裝飾器非常的簡(jiǎn)單:

  
 
  1. def deco(func): 
  2.     """無(wú)參數(shù)調(diào)用decorator聲明時(shí)必須有一個(gè)參數(shù),這個(gè)參數(shù)將接收要裝飾的方法""" 
  3.     print "before myfunc() called." 
  4.     func() 
  5.     print "after myfunc() called." 
  6.     return func 
  7.  
  8. @deco 
  9. def myfunc(): 
  10.     print " myfunc() called." 
  11.  
  12.  
  13. myfunc() 
  14. myfunc() 

定義好裝飾器后,,,即可使用。上面這個(gè)裝飾器在使用的時(shí)候有一個(gè)問(wèn)題,即只在***次被調(diào)用,并且原來(lái)的函數(shù)多執(zhí)行一次。執(zhí)行輸出如下:

  
 
  1. before myfunc() called.   
  2. myfunc() called. 
  3. after myfunc() called. 
  4.  myfunc() called.   --函數(shù)多執(zhí)行一次的輸出 
  5.  myfunc() called.   --第二次調(diào)用,裝飾器不生效 

要保證新函數(shù)每次被調(diào)用,使用下面的方法來(lái)定義裝飾器

  
 
  1. def deco(func): 
  2.     """無(wú)參數(shù)調(diào)用decorator聲明時(shí)必須有一個(gè)參數(shù),這個(gè)參數(shù)將接收要裝飾的方法""" 
  3.     def _deco(): 
  4.         print "before myfunc() called." 
  5.         func() 
  6.         print "after myfunc() called." 
  7.         #return func 不需要返回func 
  8.     retrun _deco 
  9. @deco 
  10. def myfunc(): 
  11.     print " myfunc() called." 
  12.     return 'OK' 
  13. myfunc() 
  14. myfunc() 

函數(shù)輸出如下:

  
 
  1. before myfunc() called. 
  2.  myfunc() called. 
  3.   after myfunc() called. 
  4. before myfunc() called. 
  5.  myfunc() called. 
  6.   after myfunc() called. 

這樣可以看到,裝飾器每次都得到了調(diào)用。

3.2帶參數(shù)的函數(shù)進(jìn)行裝飾器

  
 
  1. def deco(func): 
  2.     def _deco(a, b): 
  3.         print("before myfunc() called.") 
  4.         ret = func(a, b) 
  5.         print("  after myfunc() called. result: %s" % ret) 
  6.     return ret 
  7. return _deco 
  8.  
  9. @deco 
  10. def myfunc(a, b): 
  11.     print(" myfunc(%s,%s) called." % (a, b)) 
  12.     return a + b 
  13.   
  14. myfunc(1, 2) 
  15. myfunc(3, 4) 

輸出:

  
 
  1. before myfunc() called. 
  2. myfunc() called. 
  3. After myfunc() called. result: 3 
  4. before myfunc() called. myfunc() called. After myfunc() called. result: 7 

內(nèi)嵌函數(shù)的形參和返回值與原函數(shù)相同,裝飾函數(shù)返回內(nèi)嵌包裝函數(shù)。

3.3裝飾器帶參數(shù)

  
 
  1. def decoWithArgs(arg): 
  2. """由于有參數(shù)的decorator函數(shù)在調(diào)用時(shí)只會(huì)使用應(yīng)用時(shí)的參數(shù)而不接收被裝飾的函數(shù)做為參數(shù), 
  3.    所以必須返回一個(gè)decorator函數(shù), 由它對(duì)被裝飾的函數(shù)進(jìn)行封裝處理""" 
  4. def newDeco(func):    #定義一個(gè)新的decorator函數(shù) 
  5.     def replaceFunc():    #在decorator函數(shù)里面再定義一個(gè)內(nèi)嵌函數(shù),由它封裝具體的操作 
  6.         print "Enter decorator %s" %arg    #進(jìn)行額外操作 
  7.         return func()    #對(duì)被裝飾函數(shù)進(jìn)行調(diào)用 
  8.     return replaceFunc 
  9. return newDeco    #返回一個(gè)新的decorator函數(shù) 
  10.  
  11. @decoWithArgs("demo") 
  12. def MyFunc():    #應(yīng)用@decoWithArgs修飾的方法 
  13.     print "Enter MyFunc" 
  14.  
  15. MyFunc()    #調(diào)用被裝飾的函數(shù) 

輸出:
nter decorator demo
Enter MyFunc

這個(gè)情形適用于原來(lái)的函數(shù)沒(méi)有參數(shù),新增加打印的情況。常見(jiàn)適用的地方是增加函數(shù)的打印日志。

3.4對(duì)參數(shù)數(shù)量不確定的函數(shù)進(jìn)行裝飾

下面的例子是一個(gè)郵件異步發(fā)送的例子,函數(shù)的參數(shù)數(shù)據(jù)部確定,裝飾器實(shí)現(xiàn)了對(duì)于郵件發(fā)送函數(shù)的異步發(fā)送。

  
 
  1. from threading import Thread 
  2.  
  3. def async(f): 
  4.     def wrapper(*args, **kwargs): 
  5.         thr = Thread(target = f, args = args, kwargs = kwargs) 
  6.         thr.start() 
  7.     return wrapper 
  8.  
  9. @async 
  10. def send_async_email(msg): 
  11.     mail.send(msg) 
  12.  
  13. def send_email(subject, sender, recipients, text_body, html_body): 
  14.     msg = Message(subject, sender = sender, recipients = recipients) 
  15.     msg.body = text_body 
  16.     msg.html = html_body 
  17.     send_async_email(msg) 

并且這個(gè)裝飾器可以適用一切需要異步處理的功能,做到非常好的代碼復(fù)用。

3.5讓裝飾器帶類參數(shù)

  
 
  1. class locker: 
  2.     def __init__(self): 
  3.         print("locker.__init__() should be not called.") 
  4.           
  5.     @staticmethod 
  6.     def acquire(): 
  7.         print("locker.acquire() called.(這是靜態(tài)方法)") 
  8.           
  9.     @staticmethod 
  10.     def release(): 
  11.         print("  locker.release() called.(不需要對(duì)象實(shí)例)") 
  12.   
  13. def deco(cls): 
  14.     '''cls 必須實(shí)現(xiàn)acquire和release靜態(tài)方法''' 
  15.     def _deco(func): 
  16.         def __deco(): 
  17.             print("before %s called [%s]." % (func.__name__, cls)) 
  18.             cls.acquire() 
  19.             try: 
  20.                 return func() 
  21.             finally: 
  22.                 cls.release() 
  23.         return __deco 
  24.     return _deco 
  25.   
  26. @deco(locker) 
  27. def myfunc(): 
  28.     print(" myfunc() called.") 
  29.   
  30. myfunc() 
  31. myfunc() 

輸出為:

  
 
  1. before myfunc called [__main__.locker]. 
  2. locker.acquire() called.(this is staticmethon) 
  3. myfunc() called. 
  4.   locker.release() called.(do't need object ) 
  5.  
  6. before myfunc called [__main__.locker]. 
  7. locker.acquire() called.(this is staticmethon) 
  8. myfunc() called. 
  9.   locker.release() called.(do't need object ) 

裝飾器總結(jié)

當(dāng)我們對(duì)某個(gè)方法應(yīng)用了裝飾方法后, 其實(shí)就改變了被裝飾函數(shù)名稱所引用的函數(shù)代碼塊入口點(diǎn),使其重新指向了由裝飾方法所返回的函數(shù)入口點(diǎn)。由此我們可以用decorator改變某個(gè)原有函數(shù)的功能,添加各種操作,或者完全改變?cè)袑?shí)現(xiàn)。

參考文章

感謝以下幾位大神:

http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

http://www.cnblogs.com/Jifangliang/archive/2008/07/22/1248313.html

http://www.cnblogs.com/vamei/archive/2013/02/16/2820212.html


文章標(biāo)題:Python 裝飾器學(xué)習(xí)以及實(shí)際使用場(chǎng)景實(shí)踐
標(biāo)題鏈接:http://m.5511xx.com/article/cogeiio.html