Python 裝飾器之 functools.wraps

發表於2016-10-27

Decorator

在以前的 Blog 中曾經簡單寫過 Decorator。這次需要講的更細一些。

Decorator 通過返回包裝物件實現間接呼叫,以此插入額外邏輯。是從老大那邊偷來的哪裡摘抄來的,應該算是言簡意賅了。

可以還原成

可以還原成

這個過程中執行了下面幾步

  1. 函式 foo 作為 裝飾器 outer 的引數被傳入
  2. 函式 inner 對 func 進行呼叫,然後裝飾器 outer 返回 inner
  3. 原來的函式名 foo 關聯到 inner,如上面的foo 所示,呼叫 foo 時間上是在呼叫 inner

裝飾器不僅可以用函式返回包裝物件,也可以是個類,不過這種方法太尼瑪囉嗦,這裡就不介紹了,想了解的自己去翻吧。下面我們寫一個有點用處的 Decorator。 假想我們有個coordinate類,而且這個類提供了 x, y座標,而我們要對兩個coordinate 物件進行計算。程式碼如下:

上面例子中的sub(one, two)three都有負數,當我們把座標限制在第一象限時,這兩個就不符合我們的要求,用 Decorator 來做一個檢測再好不過了

這樣,只計算的函式addsub前面加一個 Decorator 就可以完成座標的校驗。比在函式內實現要優雅一些。

Decorator 還可以為類增加額外的成員,

functools.wraps

我們在使用 Decorator 的過程中,難免會損失一些原本的功能資訊。直接拿 stackoverflow 裡面的栗子

而functools.wraps 則可以將原函式物件的指定屬性複製給包裝函式物件, 預設有 __module____name____doc__,或者通過引數選擇。程式碼如下:

相關文章