Python3-裝飾器 裝飾器
阿新 • • 發佈:2018-12-26
裝飾器(語法糖)
裝飾器的本質:一個閉包函式
裝飾器的功能:在不修改原函式及其呼叫方式的情況下對原函式功能進行擴充套件
例子1.
給hahaha函式加上一個timmer(計算函式執行時間)的功能。
import time def timmer(func): #函式名可以當做函式的引數 def inner(): start = time.time() func() end = time.time() print(start - end) return inner # 語法糖 @timmer # @把hahaha函式名作為引數傳到timmer(),執行了一次, 然後進行了重新賦值 hahaha= timmer(hahaha) --> inner() def hahaha(): time.sleep(0.1) print('aaaa') # time(hahaha) 不能改變這個函式的呼叫方式 # 也不能修改原始碼 # hahaha = timmer(hahaha) timmer(hahaha)函式的執行結果返回 inner函式的記憶體地址,然後賦值給hahaha # hahaha() 就等同於 inner() hahaha()
裝飾器的設計模式:開放封閉原則
開放:對擴充套件是開放的
封閉:對修改是封閉的
剛剛我們討論的裝飾器都是裝飾不帶引數的函式,現在要裝飾一個帶引數的函式怎麼辦?
import time def timer(func): def inner(*args, **kwargs): start_time = time.time() func(*args, **kwargs) end_time = time.time() print(end_time - start_time) return inner @timer def func1(a): time.sleep(2) print(a) func1('bb')
帶引數的裝飾器
def outer(flag): def timer(func): def inner(*args, **kwargs): if flag: print('執行函式之前要做的') func(*args, **kwargs) if flag: print('執行函式之後要做的') return inner return timer @outer(True) def func2(mode): print(111, mode) func2('rrr')
多個裝飾器裝飾同一個函式
有些時候,我們也會用到多個裝飾器裝飾同一個函式的情況。
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()
輸出:
wrapper2 ,before func wrapper1 ,before func in f wrapper1 ,after func wrapper2 ,after func