python 裝飾器 Decorator

來源:互聯網
上載者:User

標籤:就會   方式   imp   return   turn   cto   func   簽名   too   

一、裝飾器定義

在代碼運行期間動態增加功能的方式,稱之為“裝飾器”(Decorator)。本質上,Decorator就是一個返回函數的高階函數。

 1 >>> def log(func): 2 ...     def wrapper(*args, **kw): 3 ...         print(‘call %s:‘ % func.__name__) 4 ...         return func(*args, **kw) 5 ...     return wrapper 6 ...  7 >>> @log 8 ... def now(): 9 ...     print(‘2017-12-16‘)10 ... 11 >>> now()12 call now:13 2017-12-1614 >>> 

觀察上面的log,因為它是一個decorator,所以接受一個函數作為參數,並返回一個函數。要藉助Python的@文法,把decorator置於函數的定義處。

@log放到now()函數的定義處,相當於執行了語句:

1 >>>now = log(now)

二、帶傳參的裝飾器

 1 >>> def log(text): 2 ...     def decorator(func): 3 ...         def wrapper(*args, **kw): 4 ...             print(‘%s %s:‘ % (text, func.__name__)) 5 ...             return func(*args, **kw) 6 ...         return wrapper 7 ...     return decorator 8 ...  9 >>> @log(‘execute‘)10 ... def now():11 ...     print(‘2017-12-16‘)12 ... 13 >>> now()14 execute now:15 2017-12-16

和兩層嵌套的decorator相比,3層嵌套的效果是這樣的:

1 >>> now = log(‘execute‘)(now)

三、functools.wraps

以上兩種decorator的定義都沒有問題,但還差最後一步。因為我們講了函數也是對象,它有__name__等屬性,但你去看經過decorator裝飾之後的函數,它們的__name__已經從原來的‘now‘變成了‘wrapper‘

1 >>> now.__name__2 ‘wrapper‘

因為返回的那個wrapper()函數名字就是‘wrapper‘,所以,需要把原始函數的__name__等屬性複製到wrapper()函數中,否則,有些依賴函數簽名的代碼執行就會出錯。

不需要編寫wrapper.__name__ = func.__name__這樣的代碼,Python內建的functools.wraps就是幹這個事的,所以,一個完整的decorator的寫法如下:

1 import functools2 3 def log(func):4     @functools.wraps(func)5     def wrapper(*args, **kw):6         print(‘call %s():‘ % func.__name__)7         return func(*args, **kw)8     return wrapper
 1 import functools 2  3 def log(text): 4     def decorator(func): 5         @functools.wraps(func) 6         def wrapper(*args, **kw): 7             print(‘%s %s():‘ % (text, func.__name__)) 8             return func(*args, **kw) 9         return wrapper10     return decorator

 

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.