1. 程式人生 > >python中裝飾器的簡單理解

python中裝飾器的簡單理解

裝飾器

裝飾器也屬於閉包的一種

#裝飾器是一個很著名的設計模式,經常被用於有切面需求的場景,較為經典的有插入日誌、效能測試、事務處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量函式中與函式功能本身無關的雷同程式碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的物件新增額外的功能。

import time
def decore(func):               #decore為修飾名,可以隨意指定,但需要遵循變數命名原則。
											#且func同理,但func傳入的是@修飾符以下的第一個函式。
                        #定義了一個計時器函式,傳入一個要計時的函式,並返回另一個附加了計時功能的方法
    def say():                  #定義內部函式,此功能為計算程式執行時間
                        #定義一個內嵌的包裝函式,給傳入的函式加上計時功能的包裝
        a = time.time()
        func()                  #在此呼叫函式
        b = time.time()
        total_time = b - a
        print(total_time)
    return say              #在外部函式返回內部函式的值,形成閉包
                        #將包裝後的函式返回
@decore
def hanshu():                       #需要修飾的函式,自我理解修飾器就是用作測量或者其他功能的工具。
    a = [i for i in range(1,301)]
    b1 = a[0]
    b2 = a[0]
    for i in range(len(a)):
        if a[i] > b1:
            b1 = a[i]
    for i in range(len(a)):
        if a[i] < b2:
            b2 = a[i]
    print("最大值為%d,最小值為%d"%(b1,b2))

hanshu()

python中可以在函式裡面定義另一個函式,也就是說函式可以賦給其他變數,也可以返回一個函式。
裝飾器能夠讓你在裝飾前後執行程式碼而無須改變函式本身內容。

轉載
手動裝飾器

# 裝飾器是一個函式,而其引數為另外一個函式  
def my_shiny_new_decorator(a_function_to_decorate) :  
   
    # 在內部定義了另外一個函式:一個封裝器。  
    # 這個函式將原始函式進行封裝,所以你可以在它之前或者之後執行一些程式碼  
    def the_wrapper_around_the_original_function() :  
   
        # 放一些你希望在真正函式執行前的一些程式碼  
        print "Before the function runs"  
   
        # 執行原始函式  
        a_function_to_decorate()  
   
        # 放一些你希望在原始函式執行後的一些程式碼  
        print "After the function runs"  
   
    #在此刻,"a_function_to_decrorate"還沒有被執行,我們返回了建立的封裝函式  
    #封裝器包含了函式以及其前後執行的程式碼,其已經準備完畢  
    return the_wrapper_around_the_original_function  
   
# 現在想象下,你建立了一個你永遠也不遠再次接觸的函式  
def a_stand_alone_function() :  
    print "I am a stand alone function, don't you dare modify me"  
   
a_stand_alone_function()  
#輸出: I am a stand alone function, don't you dare modify me  
   
# 好了,你可以封裝它實現行為的擴充套件。可以簡單的把它丟給裝飾器  
# 裝飾器將動態地把它和你要的程式碼封裝起來,並且返回一個新的可用的函式。  
a_stand_alone_function_decorated = my_shiny_new_decorator(a_stand_alone_function)  
a_stand_alone_function_decorated()  
#輸出 :  
#Before the function runs  
#I am a stand alone function, don't you dare modify me  
#After the function runs

現在你也許要求當每次呼叫a_stand_alone_function時,實際呼叫卻是a_stand_alone_function_decorated。實現也很簡單,可以用my_shiny_new_decorator來給a_stand_alone_function重新賦值。