Python裏的裝飾器

裝飾器

裝飾器是幹什麼用的?
裝飾器能夠在不修改某個函數的狀況下,給函數添加功能。
形象點來講,從前有一個王叔叔,他一我的住在家裏,天天打掃家,看書。因而定義以下一個函數:python

def uncle_wang():
    sweeping()
    reading()

後來呢,有一天,大頭兒子一家搬到了王叔叔隔壁 :-D 。根據劇情,一天,大頭兒子的媽媽請王叔叔來家裏吃飯,那麼,王叔叔的日程就添加了「去隔壁吃飯」這一項,可是又不能修改王叔叔以前的日程,怎麼實現?這時,就能夠給王叔叔添加一個裝飾器,給這個裝飾器起個名字,姑且就叫neighbor,而後就寫成這樣:app

@neighbor
def uncle_wang():
    sweeping()
    reading()

而後王叔叔去大頭兒子家吃飯就提上日程啦,哈哈。(只是吃飯哦,不要想多了(⊙v⊙))
這個neighbor其實也是個函數,參數就是uncle_wang(沒錯,能夠把函數名當成參數傳來傳去,還能當作返回值),在裝飾器裏面實現「去隔壁吃飯」:函數

def neighbor(func):
    eat_next_door()     # 自定義函數,去隔壁吃飯
    return func         # 原來的函數不變,直接返回

最後是執行,直接運行uncle_wang()便可網站

# 執行函數
uncle_wang()    # 至關於不加裝飾器,直接執行 neighbor(uncle_wang)()

這感受就像是用neighbor裝飾了uncle_wang,豐富了王叔叔的生活,今後變成了隔壁老王。實現方式就是套娃,給uncle_wang套個neighbor,變成neighbor(uncle_wang)(這整個東西是個函數名),而後調用這個函數: neighbor(uncle_wang)(),形如:函數名()
在Python裏,這個套娃的操做簡化成了裝飾器,直接在原函數上面添加@neighbor,而後調用的時候仍是寫成uncle_wang(),可是這個裝飾過的王叔叔已經不是原來的王叔叔了,他如今實際上是隔壁老王。code

王叔叔的新日程搞定了,可是還有個問題,就是順序。如今的日程順序至關於:教程

eat_next_door()
sweeping()
reading()

請人吃飯固然是吃晚飯啦,因此eat_next_door()須要排在最後面,而neighbor函數不能先返回(return func)而後才執行eat_next_door(),衆所周知,函數返回了就結束了,後面的東西都無論了。
因此,繼續套娃,再搞個函數進去,寫成這樣:utf-8

def neighbor(func):
    def wrapper():          # 套娃函數,注意這裏是定義,不是執行
        func()              # 至關於不帶裝飾器的 uncle_wang()
        eat_next_door()     # 自定義函數,去隔壁吃飯
    return wrapper          # 直接返回套娃函數

這樣順序就對了,王叔叔很滿意~
如今這個裝飾器基本成型了,可是如今還不能處理原函數的參數和裝飾器函數的參數,繼續改進的實現方式能夠去看廖雪峯老師的教程,寫得很不錯,我就是從那學來的。get

附上完整代碼:io

# !/usr/bin/env python3
# -*- coding: utf-8 -*-

def sweeping():
    print('sweeping')

def reading():
    print('reading')
    
def eat_next_door():
    print('eat_next_door')

def neighbor(func):
    def wrapper():          # 套娃函數,注意這裏是定義,不是執行
        func()              # 至關於不帶裝飾器的 uncle_wang()
        eat_next_door()     # 自定義函數,去隔壁吃飯
    return wrapper          # 直接返回套娃函數

@neighbor
def uncle_wang():
    sweeping()
    reading()


if __name__ == "__main__":
    uncle_wang()

(嗨,又水了一篇,以前還說要測一下手動實現和庫函數實現的二分查找的耗時差距,正事仍是放到下次吧……)class

參考資料:

  1. 裝飾器 - 廖雪峯的官方網站
  2. 隔壁老王的梗是怎麼來的 - 知乎
相關文章
相關標籤/搜索