自創最精簡的python裝飾器


個人心血原創,歡迎轉載,請注明作者和出處。否則依法追究法律責任!!!!

author:headsen  chen  

date:2018-03-21  10:37:52

 

代碼:

代碼解析過程:
1,def  w函數,分配內存,存儲變量:門牌號:w,主體內容:(print(“www”);return a),僅分配內存和標識變量名,不做任何其他的操作。

2,def  f 函數,分配內存,存儲變量,門牌號:f,主體內容: (print(‘fff’)),作用同上,f 本身代表的函數名,打印出來就是內存地址!!!一定要理解這個

3,g=w(f),細分成三步完成:

3.1,f函數作為實參傳遞到w函數中,變成了w(f),此時的w (f)函數成了如下的形式:

             

3.2,執行新的w (f)函數:即 w(f),結果是打印出 www,並自帶返回值 f ,這個返回值就之前第2步定義的f函數的函數名,也就是f 函數的內存地址

3.3,執行新變量的賦值過程:g=w(f)  ,也就是將f函數的內存地址賦值給g這個變量(此時的 f 函數的內容主體等於有兩個變量在引用它,即 f 和 g)!!!!!! 一定要理解這個

4,g(),運行g()函數,也就是運行3.3步驟中的變量主體內容,由於它調用的是和 f 函數相同的內容主體,此時執行的也就是原來的 f() 函數。

 

將上述代碼寫成python裝飾器的形式    

解說:

1,@w  等同於  f = w ( f )

2,這里的 f 被重新定義了,以后無論幾次引用都會啟用新的f 函數。新的f 函數的作用:

      print  (‘www’)

      f () 

     實現了比原來的f 函數的更多的功能,這就是裝飾器的作用:在不改變原代碼和調用的情況下,給函數增加新的功能

評論:能否理解看個人能力。我自己也是看了多遍的視頻及他人博客,前后花了好多的時間總結揣摩,最后總結出來的。如果我的這篇裝飾器還看不懂,那就找不到更深入檢出的文章了。

           一旦你理解了,你就會有一種撥雲霧而見青天的感覺。

 

擴展:給一個函數添加多個裝飾器:

執行后的效果:

 

給一個帶參數的函數添加裝飾器:

代碼如下:

代碼解析過程:

1,def  y(n)  定義一個 y 函數,分配變量名y 和內存地址,及內容主體。

2,def  f(a)  定義一個 f 函數,分配變量名f 和內存地址,及內容主體。

3,g = y(f) ,細分為三步

     3.1,將f 函數當成實參傳遞給y(n)函數,此時的y 函數變成了:

              

      3.2,執行 y(f) 函數,先定義了j這個變量,整個y函數沒有任何的執行過程,只定義了一個變量 j,取j作為y函數的返回值,即 print(y)=j.而j本身就是函數名,對應這個一個內容主體。

      3.3,g = y(f), 將上一步的 返回值 j (j函數的內存地址)賦值給g

4,g(3) ,將參數3傳遞到g的內存地址中去運行:等於實際運行的是:

            

        4.1 ,打印:yyy

        4.2, 執行return  f(3),調用f(3) 函數,打印:fff  3,當執行一個函數的時候,若return的內容是一個函數時,該函數會被正常的執行,若return的內容是一個定量或者沒有的時候,就不會在屏幕上顯示結果但作為函數的返回值真實存在。

               

 

 補充:python中的函數執行:

1,函數內容主體中執行:

                執行結果:

 

2,在函數的return中執行:

             執行結果:

總結:當一個函數執行的時候,當該函數的return內容是一個可執行的程序的時候,該程序也會正常的執行。不過此時的返回值的概念是:

 

=====》分別打印兩個函數的內存地址

 

 

=====》 盡管這次return的是a() ,但由於b()函數並沒有調用,仍然還是打印兩個函數的內存地址。

 

 

====》執行結果: 因為b()函數里面是空的。而return的a是個變量,就是一個內存地址。

 

 

====》 此時運行b函數,則b函數的主體會運行,return里面的如果是可執行程序也會運行,效果如下:

 

 

 

 

 

 

 

      

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM