Python Decorator Closure

來源:互聯網
上載者:User

http://www.cnblogs.com/tqsummer/archive/2011/01/24/1943314.html, Python和Decorator(裝飾器)模式

http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html, Python裝飾器與面向切面編程

最近在看FP相關, 看到Closure, 想起這個... python的裝飾器方法是用閉包實現的

Closure是什麼就不解釋了, 可以看上面第一個blog

 

裝飾器, 經典的設計模式, 動態地給一個對象添加一些額外的職責.

大家在寫代碼的時候, 除了核心的邏輯, 往往還有許多輔助的邏輯, 比如, log, try catch, lock, time計時, 等等...

如果都混在一起, 嚴重影響代碼的整潔度, 比如log或try catch這種需要隨處加的, 非常影響開發效率, 和可讀性

而裝飾器最大的應用, 就是將核心代碼和輔助代碼分離.

 

以time為例,大家在測performance的時候會在自己代碼裡面加上大量的這樣的代碼, 非常煩...

import timedef foo():    start = time.clock()    print 'in foo()'    end = time.clock()    print 'used:', end - start 

Python這種動態語言, function也是first-class, 所以簡單改進如下, 雖然簡單, 但是這已經屬於裝飾器設計模式
這種改動的問題在於, 你想想這種performance代碼都是臨時加上的, 如果每次都需要修改函數名來測時間, 相當麻煩

import time def foo():    print 'in foo()' def timeit(func):    start = time.clock()    func()    end =time.clock()    print 'used:', end - start 這個例子開始, 就是使用閉包(closure)來實現裝飾器模式. 其中wrapper就是個閉包, 因為裡麵包含外部變數func
好處是, 在每個需要test的function前面, 加上一個聲明就ok, 更方便一些.
有個問題需要注意的是, 完成foo = timeit(foo)後, foo的funciton name是wrapper, 而不是foo. 如果要解決這個問題, 需要使用functools.wraps
import time def foo():    print 'in foo()' def timeit(func):     def wrapper():        start = time.clock()        func()        end =time.clock()        print 'used:', end - start    return wrapper foo = timeit(foo)foo()

 

裝飾器方法的Python文法糖,@

@timeit,在定義上加上這一行與另外寫foo = timeit(foo)完全等價

import time def timeit(func):    def wrapper():        start = time.clock()        func()        end =time.clock()        print 'used:', end - start    return wrapper @timeitdef foo():    print 'in foo()'

python中內嵌的裝飾器方法, 分別是staticmethod、classmethod和property
  

再給出一個lock的例子, 對於線程lock需要傳入同一個lock對象, 更加體現出閉包
博主嫌這個方法不夠優雅, 寫了套更簡單的
把lock對象的產生封裝到一個Decorate類中, 並在類初始化是完成對於所有類函數自動的wrapper, 這個取決於python的動態特性, 可以run-time時擷取, 修改函數的邏輯.
具體可以參考第一個blog
def sync(func):    def   wrapper(*args, **kv):          self = args[0]          self.lock.acquire()          try:               return func(*args, **kv)          finally:               self.lock.release()    return wrapperclass Foo(object):       def __init__(self, …):              self.lock = threading.Lock()       @sync       def  interface1(self, …):              do something       @sync       def  interface2(self, …):              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.