Python 偏函式用法全方位解析

挖挖土豆發表於2020-06-25

Python的functools模組中有一種函式叫“偏函式”,自從接觸它以來,發現確實是一個很有用且簡單的函式,相信你看完這篇文章,你也有相見恨晚的感覺。

我們都知道,函式入參可以設定預設值來簡化函式呼叫,而偏函式的作用就是將入參進行預設填充,降低函式使用的難度

如int()函式,可以將字元型轉換為整型,且預設的都是以十進位制形式來轉換,那為什麼一定是十進位制呢?如果想用以二進位制的形式轉換呢?其實我們可以看一下int函式它本身的定義偏函式,一個讓你相見恨晚的實用函式

可以看到int有兩種用法,可以傳一個位置引數,還可以多傳一個關鍵字引數base,也就是基於什麼格式轉換,預設不傳base引數是以十進位制轉換。所以,用二進位制形式轉換的話只要base=2即可(見下方程式碼)

1 value = int('10000')
2 print(value)    # 10000
3 
4 value = int('10000', base=2)
5 print(value)    # 16

如果每次轉換的字串的時候都要輸入base引數,顯得很麻煩,因此偏函式的作用就體現出來了,可以使用functools.partial()函式來重新定義

1 from functools import partial
2 
3 int2 = partial(int, base=2)
4 res = int2('10000')
5 print(res)     # 16

到這裡,你應該已經感覺到了偏函式的一點點魅力吧,那我們再從多個角度進一步看透它。

  • 自定義函式的使用
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,所以結果就是10

  • 當入參為可變關鍵字引數時
 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)

  • 當入參為限制的關鍵字引數時
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

我們知道,當用*號分隔開,表示後面的關鍵字引數是必傳的,因此對於預設引數也是同樣適用,即當引數為必傳時,偏函式也需要對每個關鍵字引數設定預設值。因此修改後為

1 studentAge = partial(student, age=20, city='Beijing')
2 studentAge('Tom')  # name: Tom age: 20 city: Beijing

 

綜上,偏函式可以將目標函式的部分引數固化後,重新定義為新的函式,降低了編碼的複雜度,尤其是當引數很多的時候,或者只用到其中某些引數的場景下時,效果更為顯著。

到這裡,你是否有了相見恨晚的感覺呢?簡單函式小技巧,非常實用的偏函式用法就介紹完了,如果覺得有用,請關注我,後續會繼續分享更多好用好知識。

 

相關文章