2016年5月14日 星期六

Python 研究-@修飾符和裝飾器

Python的@修飾符和裝飾器
Python的修飾器的英文名叫Decorator。『@』修飾符必須出現在函數定義前一行,不允許和函數定義在同一行。也就是說@A def f(): 是非法的。 只可以在模組或類定義層內對函數進行修飾,不允許修飾一個類。
所謂裝飾器就是把原函數包裝一下,對原函數進行加工,增加一些附加功能,裝飾器本身就是一個函數,就是將被裝飾的函數當作參數傳遞給裝飾器,返回包裝後的函數:你可以試下:
def d(fp):
    def _d(*arg, **karg):
        print "do sth before fp.."
        r= fp(*arg, **karg)
        print "do sth after fp.."
        return r
    return _d

@d
def f():
    print "call f"
#上面使用@d來表示裝飾器和下面是一個意思
#f = d(f)
f()#呼叫f
裝飾器帶參數:再包裝一層被裝飾的函數還有其他參數:上面的例子包裝函數就是接收任意形式的參數
其實帶參數的裝飾器是經過呼叫」裝飾器」函數返回的一個裝飾器, 之所以裝飾器上打引號是說明這個所謂的」裝飾器」只不過是一個普通的函數, 但這個普通的函數返回一個裝飾器。
一個修飾符就是一個函數,它將被修飾的函數做為參數傳入,並返回修飾後的函數或其它可呼叫的東西。
先看一段程式碼
#!/usr/bin/python

def test(func):
    func()

@test
def fun():
    print "call fun"
上面的程式碼沒有main()呼叫或者直接的函數呼叫,結果還是會輸出
call fun
@修飾符有點像函數指針,python解釋器發現執行的時候如果碰到@修飾的函數,首先就解析它,找到它對應的函數進行呼叫,並且會把@修飾下面一行的函數作為一個函數指針傳入它對應的函數。有點繞口,這裡說的「它對應的函數」就是名字是一樣的。下面說下之前程式碼的解析流程:
1.python解釋器發現@test,就去呼叫test函數
2.test函數呼叫預先要指定一個參數,傳入的就是@test下面修飾的函數,也就是fun()
3.test()函數執行,呼叫fun(),fun()列印「call fun」
再看一段程式碼
#!/usr/bin/python

def test(func):
  func()
  print "call test over"

def main():
  @test
  def fun():
    print "call fun"
#main()
這樣呼叫的話就不會呼叫test,只有當main函數呼叫的時候才會進入到main函數,然後呼叫test
其他資料參考
Python修飾器的函數式編程
http://www.open-open.com/lib/view/open1395285030019.html
Python進階
http://www.wklken.me/category/pythonru-men-ji-jin-jie-bi-ji.html
Python裝飾器學習(九步入門)
http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html
Python深入05 裝飾器
http://www.cnblogs.com/vamei/archive/2013/02/16/2820212.html

沒有留言:

張貼留言