個人心血原創,歡迎轉載,請注明作者和出處。否則依法追究法律責任!!!!
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里面的如果是可執行程序也會運行,效果如下: