Python裝飾器學習

來源:互聯網
上載者:User

轉:http://blog.csdn.net/thy38/article/details/4471421

 

在《Core Python Programming 2nd》中學習到了裝飾器,這對我來說是個完全陌生的文法,第一遍愣是沒看懂,很有必要記一下。

 

第一眼看到這個詞Decorator,我聯想到了DP中的Decorator模式,後來才知道完全不是這麼一回事。(再次鄙視一下國內浮躁的部落格,我google了一下,幾乎千篇一律都是什麼鎖同步裝飾器、逾時裝飾器,我對原作者表達敬仰,可是大家都是轉載就不像話了,也是對網路資源的極大浪費,也許真正有價值的博文就湮沒在這片都是一模一樣的東西裡了)

 

1. 這是個什麼東東?
書上說得不是太清楚,它說類似於Java的AOP(Aspect Oriented Programming,面向方面編程),我對AOP一無所知。根據我對許多例子用法的反覆揣摩,我認為是類似於程式設計語意學中所說的前鍵 與後鍵 的概念(Eiffel中的@pre 與@post )。當然你可以在裝飾器中做比前鍵與後鍵更多的事,如:引入日誌、增加計時邏輯來檢測效能、給函數增加事務的能力。

 

其實總體說起來,裝飾器其實也就是一個函數,一個用來封裝函數的函數,返回一個修改之後的函數對象,將其重新賦值原來的標識符,並永久喪失對原始函數對象的訪問。

 

2. 裝飾器文法

(1)無參數裝飾器

 

[python] view plaincopy

 
  1. def deco(func):  
  2.     print func  
  3.     return func  
  4. @deco  
  5. def foo():pass  
  6. foo()  

 

第一個函數deco是裝飾函數,它的參數就是被裝飾的函數對象。我們可以在deco函數內對傳入的函數對象做一番“裝飾”,然後返回這個對象(記住一定要返回 ,不然外面調用foo的地方將會無函數可用。實際上此時foo=deco(foo))

 

我寫了個小例子,檢查函數有沒有說明文檔:

 

[python] view plaincopy

 
  1. def deco_functionNeedDoc(func):  
  2.     if func.__doc__ == None :  
  3.         print func, "has no __doc__, it's a bad habit."  
  4.     else:  
  5.         print func, ':', func.__doc__, '.'  
  6.     return func  
  7. @deco_functionNeedDoc  
  8. def f():  
  9.     print 'f() Do something'  
  10. @deco_functionNeedDoc  
  11. def g():  
  12.     'I have a __doc__'  
  13.     print 'g() Do something'  
  14. f()  
  15. g()  

 

 

(2)有參數裝飾器

 

[cpp] view plaincopy

 
  1. def decomaker(arg):  
  2.     '通常對arg會有一定的要求'  
  3.     """由於有參數的decorator函數在調用時只會使用應用時的參數  
  4.        而不接收被裝飾的函數做為參數,所以必須在其內部再建立  
  5.        一個函數  
  6.     """  
  7.     def newDeco(func):    #定義一個新的decorator函數  
  8.         print func, arg  
  9.         return func  
  10.     return newDeco  
  11. @decomaker(deco_args)  
  12. def foo():pass  
  13. foo()  

 

第一個函數decomaker是裝飾函數,它的參數是用來加強“加強裝飾”的。由於此函數並非被裝飾的函數對象,所以在內部必須至少建立一個接受被裝飾函數的函數,然後返回這個對象(實際上此時foo=decomaker(arg)(foo))

 

這個我還真想不出什麼好例子,還是見識少啊,只好借用同步鎖的例子了:

 

[python] view plaincopy

 
  1. def synchronized(lock):  
  2.     """鎖同步裝飾方法 
  3.     !lock必須實現了acquire和release方法 
  4.     """  
  5.     def sync_with_lock(func):  
  6.         def new_func(*args, **kwargs):  
  7.             lock.acquire()  
  8.             try:  
  9.                 return func(*args, **kwargs)  
  10.             finally:  
  11.                 lock.release()  
  12.         new_func.func_name = func.func_name  
  13.         new_func.__doc__ = func.__doc__  
  14.         return new_func  
  15.     return sync_with_lock  
  16. @synchronized(__locker)  
  17. def update(data):  
  18. """更新計劃任務"""  
  19.     tasks = self.get_tasks()  
  20.     delete_task = None  
  21.     for task in tasks:  
  22.         if task[PLANTASK.ID] == data[PLANTASK.ID]:  
  23.             tasks.insert(tasks.index(task), data)  
  24.             tasks.remove(task)  
  25.             delete_task = task  
  26.     r, msg = self._refresh(tasks, delete_task)  
  27.     return r, msg, data[PLANTASK.ID]  

 

調用時還是updae(data)。

 

同時還可以將多個裝飾器組合 使用:

 

[python] view plaincopy

 
  1. @synchronized(__locker)  
  2. @deco_functionNeedDoc  
  3. def f():  
  4.     print 'f() Do something'  

 

學後的總是感覺就是:裝飾器可以讓函數輕裝上陣,更重要的是將函數的約束放置於介面處,使意圖更加明了,同時又不增加調用者的負擔。

 

這貼子還是很膚淺的,我一定會回來的 !

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.