Python的functools模塊中有一種函數叫「偏函數」,自從接觸它以來,發現確實是一個頗有用且簡單的函數,相信你看完這篇文章,你也有相見恨晚的感受。函數
咱們都知道,函數入參能夠設置默認值來簡化函數調用,而偏函數的做用就是將入參進行默認填充,下降函數使用的難度。編碼
如int()函數,能夠將字符型轉換爲整型,且默認的都是以十進制形式來轉換,那爲何必定是十進制呢?若是想用以二進制的形式轉換呢?其實咱們能夠看一下int函數它自己的定義spa
能夠看到int有兩種用法,能夠傳一個位置參數,還能夠多傳一個關鍵字參數base,也就是基於什麼格式轉換,默認不傳base參數是以十進制轉換。因此,用二進制形式轉換的話只要base=2便可(見下方代碼)code
1 value = int('10000') 2 print(value) # 10000
3
4 value = int('10000', base=2) 5 print(value) # 16
若是每次轉換的字符串的時候都要輸入base參數,顯得很麻煩,所以偏函數的做用就體現出來了,可使用functools.partial()函數來從新定義blog
1 from functools import partial 2
3 int2 = partial(int, base=2) 4 res = int2('10000') 5 print(res) # 16
到這裏,你應該已經感受到了偏函數的一點點魅力吧,那咱們再從多個角度進一步看透它。ci
1 def add(a, b, c): 2 print('a=',a,'b=',b,'c=',c) 3 return a + b + c 4
5 add10 = partial(add, 10) 6 res = add10(1, 2) # a= 10 b= 1 c= 2
如上代碼中,partial(add, 10)入參並無指定哪一個關鍵字參數,函數卻默認的將這個值傳給了第一個參數a,那就說明,當沒有指定默認參數時,默認賦值給第一個參數,餘下參數按位置參數賦值。字符串
1 def sum(*args): 2 s = 0 3 for n in args: 4 s += n 5 return s 6
7 sum10 = partial(sum, 10) 8 print(sum10(1)) # 11
9 print(sum10()) # 10
按上述理解,沒有指定默認參數時,默認賦給第一個參數,那麼第一個參數永遠是10,後面再傳入參的話就從第二個參數開始計算,所以會實現10 + 1 = 11 的結果。一樣,若是不繼續傳參的話,只有默認的10,因此結果就是10get
1 D = {'value1':10, 'value2':20} 2 V = {'Default':100} 3 def show(**kw): 4 for k in kw: 5 print(k, kw.get(k)) 6 7 showDef = partial(show, **V) 8 showDef(**D) 9 # Default 100 10 # value1 10 11 # value2 20
同理,此時入參因爲是可變參數,所以默認是第一個傳入,先打印Default關鍵字,這裏關注一下函數的寫法,可變關鍵字參數要寫成(**V)it
1 def student(name, * , age, city): 2 print('name:',name, 'age:',age, 'city:',city) 3
4 studentAge = partial(student, age=20) 5 studentAge('Tom','Beijing') 6 # TypeError: student() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
咱們知道,當用*號分隔開,表示後面的關鍵字參數是必傳的,所以對於默認參數也是一樣適用,即當參數爲必傳時,偏函數也須要對每一個關鍵字參數設置默認值。所以修改後爲io
1 studentAge = partial(student, age=20, city='Beijing') 2 studentAge('Tom') # name: Tom age: 20 city: Beijing
綜上,偏函數能夠將目標函數的部分參數固化後,從新定義爲新的函數,下降了編碼的複雜度,尤爲是當參數不少的時候,或者只用到其中某些參數的場景下時,效果更爲顯著。
到這裏,你是否有了相見恨晚的感受呢?簡單函數小技巧,很是實用的偏函數用法就介紹完了,若是以爲有用,請關注我,後續會繼續分享更多好用好知識。