1. 程式人生 > >Python的@修飾符和裝飾器

Python的@修飾符和裝飾器

http://1.chaoxu.sinaapp.com/archives/1871 


Python的@修飾符和裝飾器

發表於  2015 年 5 月 10 日    xiaoxu

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