Python 帶參數的裝時器

摘錄整理于imooc

1. 一個帶參數的decorator例子

例子是根據 @performance('time_type')攜帶的時間類型來輸出所裝飾的函數factorial的執行時間。

import time
import functools
from past.builtins.noniterators import reduce

def performance(unit):
    def perf_decorator(f):
        # @functools.wraps應該作用在返回的新函數上。
        @functools.wraps(f)
        def wrapper(*args, **kw):
            t1 = time.time()
            r = f(*args, **kw)
            t2 = time.time()
            t = (t2 - t1) * 1000 if unit == 'ms' else (t2 - t1)
            print('call %s() in %f %s' % (f.__name__, t, unit))
            return r
        return wrapper
    return perf_decorator


@performance('ms')
def factorial(n):
    return reduce(lambda x, y: x * y, range(1, n + 1))

factorial(10000)
print(factorial.__name__)

2.代參數的decorator為什么要包三層(三階)?

# 為什么包三層(三階)
@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_decorator
def 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():
    pass
print(test())

簡而言之,最外層負責把decorator的參數DEBUG傳進來,既然decorator攜帶的參數已經傳進來,那么剩下的中間層和里層就是一個不帶參的decorator的語法糖。反之而推,要多攜帶參數,肯定是需要多加一階。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 Python的修飾器的英文名叫Decorator,當你看到這個英文名的時候,你可能會把其跟Design Pa...
    linheimx閱讀 637評論 0 4
  • 要點: 函數式編程:注意不是“函數編程”,多了一個“式” 模塊:如何使用模塊 面向對象編程:面向對象的概念、屬性、...
    victorsungo閱讀 1,562評論 0 6
  • Python進階框架 希望大家喜歡,點贊哦首先感謝廖雪峰老師對于該課程的講解 一、函數式編程 1.1 函數式編程簡...
    Gaolex閱讀 5,523評論 6 53
  • 22年12月更新:個人網站關停,如果仍舊對舊教程有興趣參考 Github 的markdown內容[https://...
    tangyefei閱讀 35,224評論 22 257
  • 本文為《爬著學Python》系列第四篇文章。從本篇開始,本專欄在順序更新的基礎上,會有不規則的更新。 在Pytho...
    SyPy閱讀 2,519評論 4 11