文章截取自https://www.cnblogs.com/lianyingteng/p/7743876.html
如果內部函數裏引用了外部函數裏定義的對象(甚至是外層之外,但不是全局變量),那麼此時內部函數就被稱爲閉包函數。
閉包可以將其自己的代碼和作用域以及外部函數的作用結合在一起。
什麼函數可以被稱爲閉包函數呢?主要是滿足兩點:函數內部定義的函數;引用了外部變量但非全局變量。
python裝飾器本質上就是一個函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外的功能,裝飾器的返回值也是一個函數對象(函數的指針)。裝飾器函數的外部函數傳入我要裝飾的函數名字,返回經過修飾後函數的名字;內層函數(閉包)負責修飾被修飾函數。從上面這段描述中我們需要記住裝飾器的幾點屬性,以便後面能更好的理解:
實質: 是一個函數
參數:是你要裝飾的函數名(並非函數調用)
返回:是裝飾完的函數名(也非函數調用)
作用:爲已經存在的對象添加額外的功能
特點:不需要對對象做任何的代碼上的變動
python裝飾器有很多經典的應用場景,比如:插入日誌、性能測試、事務處理、權限校驗等。裝飾器是解決這類問題的絕佳設計。並且從引入中的列子中我們也可以歸納出:裝飾器最大的作用就是對於我們已經寫好的程序,我們可以抽離出一些雷同的代碼組建多個特定功能的裝飾器,這樣我們就可以針對不同的需求去使用特定的裝飾器,這時因爲源碼去除了大量泛化的內容而使得源碼具有更加清晰的邏輯。
import time
def wrapper(f): #1#進入函數後直接執行return inner這句話是把原來的函數func換成inner,因
#爲inner中包含func()(@wrapper將func()作爲f導入加入到inner()中了)。
def inner(): #3# #6#
t1 = time.time()
f() #7# 這個f()是func()跳轉執行
t2 = time.time() #10#
print(t2 - t1) #11#打印晚也就是執行完inner了即執行完最後一行func()
return inner #4#
@wrapper #2#程序先執行這句話,它等價於func=wrapper(func)
def func(): #8#
time.sleep(2) #9#
func() #5#此時這個func()實際上就是inner,執行到這程序會調用inner