python中編寫帶參數decorator

來源:互聯網
上載者:User

標籤:name   重要   turn   ...   return   列印   ref   wrap   style   

考察上一節的 @log 裝飾器:

def log(f):    def fn(x):        print ‘call ‘ + f.__name__ + ‘()...‘        return f(x)    return fn

發現對於被裝飾的函數,log列印的語句是不能變的(除了函數名)。

如果有的函數非常重要,希望列印出‘[INFO] call xxx()...‘,有的函數不太重要,希望列印出‘[DEBUG] call xxx()...‘,這時,log函數本身就需要傳入‘INFO‘或‘DEBUG‘這樣的參數,類似這樣:

@log(‘DEBUG‘)def my_func():    pass

把上面的定義翻譯成高階函數的調用,就是:

my_func = log(‘DEBUG‘)(my_func)

上面的語句看上去還是比較繞,再展開一下:

log_decorator = log(‘DEBUG‘)my_func = log_decorator(my_func)

上面的語句又相當於:

log_decorator = log(‘DEBUG‘)@log_decoratordef my_func():    pass

所以,帶參數的log函數首先返回一個decorator函數,再讓這個decorator函數接收my_func並返回新函數:

def log(prefix):    def log_decorator(f):        def wrapper(*args, **kw):            print ‘[%s] %s()...‘ % (prefix, f.__name__)            return f(*args, **kw)        return wrapper    return log_decorator@log(‘DEBUG‘)def test():    passprint test()

執行結果:

[DEBUG] test()...None

對於這種3層嵌套的decorator定義,你可以先把它拆開:

# 標準decorator:def log_decorator(f):    def wrapper(*args, **kw):        print ‘[%s] %s()...‘ % (prefix, f.__name__)        return f(*args, **kw)    return wrapperreturn log_decorator# 返回decorator:def log(prefix):    return log_decorator(f)

拆開以後會發現,調用會失敗,因為在3層嵌套的decorator定義中,最內層的wrapper引用了最外層的參數prefix,所以,把一個閉包拆成普通的函數調用會比較困難。不支援閉包的程式設計語言要實現同樣的功能就需要更多的代碼。

python中編寫帶參數decorator

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.