Python學習日誌之二-----裝飾器

寫在前面的

      不管是過去還是現在,二總是個貶義詞。可是,我卻喜歡這個數字。這證明,在你做出初步嘗試後,成功的往前踏了一步。

裝飾器的類比

      裝飾器在C#中可以類比Attribute,實現在方法執行前或執行後進行初始化或者掃尾工作。裝飾器的實現實際上基於函數式編程。即傳遞一個函數參數,進行某些操作後,返回裝飾加工之後的函數。這個返回的函數也許是原函數的偏函數,也許是另外一個函數。

      既然是基於私有函數,那麼可能就會存在父函數的作用域。由此帶來了編程中的流行概念閉包。

裝飾器解釋

      裝飾器最早在Python 2.5中出現,它最初被用於加工函數和方法這樣的可調用對象(callable object,這樣的對象定義有__call__方法)。在Python 2.6以及之後的Python版本中,裝飾器被進一步用於加工類。(引用於http://www.cnblogs.com/vamei/archive/2013/02/16/2820212.html

      從本質上講,這些特徵引入了C#開發者稱之爲AOP(面向方面編程)的概念。你可以考慮在裝飾器中置入通用功能的代碼來降低程序複雜度。例如,可以用裝飾器來實現:

        1、 引入日誌

        2、 給函數加入事務能力

裝飾器舉例

 

def decorator(F):
    def new_F(a, b):
        print("input", a, b)
        return F(a, b)
    return new_F

# get square sum
@decorator
def square_sum(a, b):
    return a**2 + b**2

# get square diff
@decorator
def square_diff(a, b):
    return a**2 - b**2

print(square_sum(3, 4))
print(square_diff(3, 4))

      從上面代碼中可以發現,裝飾器函數一定會返回一個加工後的函數,否則,調用被裝飾函數時會彈出空引用。

閉包

      閉包是基於父函數名字空間被外部引用,《python核心編程》一書作者稱其爲流浪作用域。但是這些流浪者會帶來有意思的故事。

閉包與裝飾器聯合舉例

 

#!/usr/bin/env python

from time import time

def logged(when):
    def log(f,*args,**kargs):
        print '''called:
        function:%s
        args:%r
        kargs:%r''' % (f,args,kargs)

    def pre_logged(f):
        def wrapper(*args,**kargs):
            log(f,*args,**kargs)
            return f(*args,**kargs)
        return wrapper

    def post_logged(f):
        def wrapper(*args,**kargs):
            now=time()
            try:
                return f(*args,**kargs)
            finally:
                log(f,*args,**kargs)
                print "time delta:%s" % (time()-now)
        return wrapper
    try:
                return {'pre':pre_logged,'post':post_logged}[when]
    except KeyError,e:
                raise ValueError(e),'must be "pre" or "post"'
@logged('pre')
def hello(name):
    print 'hello,',name
hello('world')

      這段例子中有三層函數,請一定要注意函數的作用域。如果理解了函數作用域後,該段代碼比較好理解。

      由於是首次學習Python,所以博客水平有限,望大家多多支持。

發佈了27 篇原創文章 · 獲贊 20 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章