函數修飾器: Python @的用法

函數修飾器
裝飾器的強大在於它能夠在不修改原有業務邏輯的情況下對代碼進行擴展,權限校驗、用戶認證、日誌記錄、性能測試、事務處理、緩存等都是裝飾器的絕佳應用場景,它能夠最大程度地對代碼進行複用。

首先我們假設我們有一份菜單,這份菜單有餐點的成本,而餐廳老闆希望使用餐點的成本的1.2倍作為售價,實作如下:

class menu:
  def __init__(self):
    self.dishCost={
            "大麥克"  :  70,
            "雙層牛肉吉士堡"  :  60,
            "麥脆雞(2塊)"  :  100,
            "麥香魚"  :  50
    }
  def price(self,tag):
    return self.dishCost[tag]*1.2

m = menu()
print(m.price("大麥克"))

>> 84.0

過了幾天 老闆決定要加收服務費(餐點價格的10%),但我不想改到之前的函示,這時候就可以使用修飾器:

class menu:
  def __init__(self):
    self.dishCost={
            "大麥克"  :  70,
            "雙層牛肉吉士堡"  :  60,
            "麥脆雞(2塊)"  :  100,
            "麥香魚"  :  50
    }
  def serviceFee(mth):
    def args(self,tag):
      return mth(self,tag)*1.1
    return args

  @serviceFee
  def price(self,tag):
    return self.dishCost[tag]*1.2

m = menu()
print(m.price("大麥克"))

>> 92.4

又過了幾天 老闆說要有系統操作紀錄,但每個函數都要動的話很麻煩也不簡潔,這時候也可以用修飾器:

class menu:
  def __init__(self):
    self.dishCost={
            "大麥克"  :  70,
            "雙層牛肉吉士堡"  :  60,
            "麥脆雞(2塊)"  :  100,
            "麥香魚"  :  50
    }
    self.recept=""
    self.orders=[]
  
  def addlog(label):
    def main(mth):
      def args(self,tag):
        self.recept+=label
        self.recept+="\n"
        return mth(self,tag)
      return args
    return main

  def serviceFee(mth):
    def args(self,tag):
      return mth(self,tag)*1.1
    return args

  
  @addlog("select price")
  @serviceFee
  def price(self,tag):
    return self.dishCost[tag]*1.2

  @addlog("order dish")
  def orderDish(self,tag):
    return self.orders.append(tag)

m = menu()
m.price("大麥克")
m.orderDish("大麥克")
m.orderDish("麥香魚")
print(m.recept)

>> select price
>> order dish
>> order dish

 

Tags:

Add a Comment

發佈留言必須填寫的電子郵件地址不會公開。