1. 程式人生 > >python_裝飾器的心得分享

python_裝飾器的心得分享

函數名 需要 傳遞 真的 就是 fun name 可能 區別

  今天詳細的研究了一下裝飾器,怎麽說呢,這個語言這種東西真的是要不斷去消化和理解的,單純的依靠外來的資源是比較難去學明白的,如果你還不明白裝飾器那麽不妨往下讀一讀,當你明白了裝飾器之後,我們都會發現這個東西不是我們想象的那麽難的一件事,但是我們如果想給一個完全沒了解的人講明白他的原理以及一些操作的時候就會發現有的東西,只可意會而不能去言傳。哈哈哈,我這個人廢話好多。  

  那麽,開始了!

  簡單介紹一下裝飾器的原理,以及裝飾器的作用。在進行一些軟件的開發時,牛逼的項目經理不免會在這個產品成型之後或者說是這個產品做到了一半的時候臨時告訴你我們需要在這個功能上新加一個功能。那麽,如果我們開始修改源代碼,有可能因為一個字符轉換或者一個變量而出現一大堆問題,更甚至導致整個系統崩潰。所以我們需要使用我們的裝飾器來避免這一問題,那麽裝飾器是如何做到的呢。小兄弟,這個問題問的好。裝飾器本質上就是一個函數,確切的說是一個可以對其他函數進行功能添加的函數,在規則上裝飾器不能修改函數的源代碼和調用方式。那麽滿足上一句話的函數我們就叫他裝飾器,或者說是裝飾函數(花裏花哨的東西總有一個土到掉渣的名字)。

  那麽了解了裝飾器的定義之後,我們開始煮栗子

 1 def best(func):
 2     def ok_1(*regs):
 3         print ("老實說")
 4         func(*regs)
 5     return ok_1
 6 
 7 @best #text_1 = best(text_1)
 8 def text_1():
 9     print ("我是最棒的")
10      
11 @best    
12 def text_2(name):
13     print ("我喜歡你",name)
14 
15 text_1()
16 text_2("
白菜")

這就是一個簡單的但是全面的栗子

我們一步一步來把它實現出來

我們第一步功能是執行text_1(),text_2()之後,分別打印我是最棒的和我喜歡你

代碼如下

def text_1():
    print("我是最棒的")
    
def text_2():
    print("我喜歡你")
    
text_1()
text_2()

添加功能在打印兩句話之前,再打印“老實說”,並且不能改變兩個函數的源代碼,

那麽如何實現呢,我們可以再定義一個函數用來打印“老實說”這三個字,之後在這個函數裏面調用我們的text_1()和text_2()這兩個函數,然後我們可以在最後調用這個函數就可以了

代碼如下

 1 def laoshishuo(func):
 2     print("老實說")
 3     func()
 4 
 5 def text_1():
 6     print("我是最棒的")
 7     
 8 def text_2():
 9     print("我喜歡你")
10     
11 laoshishuo(text_1)
12 laoshishuo(text_2)

下一步我們思索

不能改變調用的函數名字,(因為我們最後實現功能是靠調用了laoshishuo(text_1)和laoshishuo(text_2)這兩個函數來實現)

最後實現功能的時候依舊要調用我們的

 1 text_1() 2 text_2() 

這兩行代碼來實現功能

就是一個符合定義的裝飾器啦,在這裏我們使用嵌套函數

代碼如下

技術分享圖片高階+嵌套=修飾器

當然了,偉大的前輩發現這兩行代碼只要是需要修飾器就得寫一次,於是

def qiantao(func):
    def laoshishuo():
        print("老實說")
        func()
    return laoshishuo

@qiantao  # text_1 = qiantao(text_1) 
def text_1():
    print("我是最棒的")
@qiantao  #text_2 = qiantao(text_2)
def text_2():
    print("我喜歡你")

text_1()
text_2()

這個@qiantao 學名叫做語法糖就應運而生 對 就是這麽萌的一個名字,好吧,這不是重點

好,我們現在來一步一步看一下這個代碼。

先定義函數qiantao,沒問題吧;

調用時裏面寫參數可以傳遞,沒問題吧;

註意了這個return 不知道大家怎麽旸,我當時是被整暈了,在這裏我們要理解 laoshishuo 和 laoshishuo()有什麽區別,簡單的來說前者是個內存地址,而後者是把這個內存地址的程序讀出來運行,沒問題吧;

在這裏返回一個laoshishuo 是什麽作用呢,瞪大眼睛看下面這一段話,

我們把參數傳進這個qiantao之後,qiantao這個函數使用了我們傳進去的參數定義了一個函數叫做laoshishuo,

對!!!和你現在想的一樣

現在的laoshishuo不再是

print("老實說")

func()

而是

print("老實說")

傳進去的參數()

並且存了起來

那麽返回laoshishuo這個內存地址,而且是已經變成

print("老實說")

傳進去的參數()

的laoshishuo地址

把這個返回值通過語法糖給了text_1那麽結果就十分清晰了

所以運行text_1就是運行了這個改變後的laoshishuo

print(“老實說”)

text_1()

這就是我們目的,我們的功能就這樣實現了,沒有改變源碼,沒有改變調用方式,

在這之後所有的函數只要前面加上了這個語法糖,那麽就可以實現修飾的作用了

沒問題吧;

當然在對我們的修飾函數進行稍加修改就可以變成我們最開始的那個代碼,沒問題吧;

實現的現象如下

技術分享圖片

好了,這就是我的一點對於裝飾器的理解,寫的不好,有錯誤的勞煩各位老師指出,拜謝拜謝

python_裝飾器的心得分享