Python是一門入門容易精通難的語言,可能你花1-2個月就能入門,但是随着時間的深入,你越研究發現Python内在的内容很深,而且很複雜! Python中難的知識點很多。
今天我們來介紹一下類裝飾器,我們前面入門的文章裡面寫過一些關于裝飾器知識(2道極好的Python算法題|帶你透徹了解裝飾器的妙用),今天來介紹一下更複雜的類裝飾器.
我們看到很多源碼比如大名鼎鼎的Flask架構裡面經常有這樣的代碼:app = Flask(__name__)@app.route('/')defhello_world(): return'This Index Page'
代碼很簡潔,但是資訊量巨大,這是什麼鬼,根本看不懂!入門1個月内的同學基本上都看不懂,或者根本不了解這段代碼。Python學的越深,越會被這樣的問題而困擾,越想去探求Python内在的原理,這也是通往Python進階之路必修之路!
1.先來一個最最簡單的類裝飾器classHiDecorate: definfo(self,func): func()decorate=HiDecorate()@decorate.infodeff(): print ('Hi Decorate')>>Hi Decorate
HiDecorate類裡面有一個函數叫info.當我們使用類裝飾器的時候,其實就是把f當作變量傳給info裡面的func.不信我們加兩行代碼:
但是我們如果直接調用f()會報錯,因為info裡面沒有任何傳回的函數位址,也就是說傳回的是none,肯定會報錯!我們繼續探索。
2.函數帶參數
看懂了上面的最簡單的類裝飾之後,我們要稍微加點料了,我們給f函數加參數,如果還是按照上面的寫法肯定會報錯:因為a,b兩個參數沒有傳遞給info,這個是調用func():
一定會報“TypeError: f() missing 2 required positional arguments: 'a' and 'b'”
是以我們需要加上一個閉包來傳進來a,bclassHiDecorate: definfo(self,func): defwrap(*args): print ('func name:{},args:{}'.format(func.__name__,args)) func(*args) returnwrap decorate=HiDecorate()@decorate.infodeff(a,b): print ('Hi Decorate')f(1,2)>>funcname:f,args:(1,2)Hi Decorate
(代碼可以左右滑動看)
3.增加一些複雜度
我們把上面的稍微複雜一點,比如我們有相加add,相乘mul兩個函數,需要計算cost時間
>>func name:add,args:(1, 2),call_time:07/22/18 18:43:08
>>a+b=3,sleep:1.0
func name:mul,args:(1, 2),call_time:07/22/18 18:43:08
>>a+b=3,sleep:0.8
4. 最複雜的裝飾器帶參數
有的時候我們需要在裝飾器上帶參數,增加函數的功能和靈活性。比如我們在
@decorate.info()裡面帶參數來擴充功能。
>>format: y
format: Y
func name:f1,args:(1, 2),call_time:18-07-22
Hi Decorate
func name:f2,args:(1, 2),call_time:2018-07-22
Hi Decorate
其實就是我們需要在原來的基礎上再進行一層封裝,這樣才能把裝飾器函數後面的參數帶進去。
5.剛才的類裝飾器顯得有點臃腫,我們再次封裝來簡化
總結:
這個時候,你再去看開頭Flask那段源碼,就會明白了!app = Flask(__name__)@app.route('/')defhello_world(): return'This Index Page'
類裝飾器router是調用app下面的route函數,裡面的'/',傳遞給了rule參數,而hello_world函數的位址傳遞給了decorator裡面的f參數。defroute(self, rule, **options): defdecorator(f): endpoint = options.pop('endpoint', None) self.add_url_rule(rule, endpoint, f, **options) returnf returndecorator
(代碼可以左右滑動看)
接着再decorator裡面又繼續封裝了一層去調用app類裡面的all_url_rule函數了.一層套一層,需要抽絲剝繭,慢慢的去體會!
Python是一門入門容易精通難的語言,進階之路會很慢也會很痛苦,想要翻過這座山,必須深入的研究Python内在之美,了解内在機制,經過修煉你的Python功力才會大增,才寫出一手讓人眼前一亮的code,加油吧,少年!