偏函數(partial)把函數部分的參數固定下來,至關於爲部分參數添加了一個固定的默認值,並返回一個新的可調用對象。
使用partial生成的新函數,是對原函數的封裝。
基於一個函數建立一個新的可調用對象,把原函數的某些參數固定。
使用這個函數能夠把接受一個或多個參數的函數改變成須要回調的API,這樣參數更少。html
按照官方說法,偏函數的實現原理大體等價於如下代碼:python
def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) return func(*args, *fargs, **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc
固定關鍵字參數yapp
from functools import partial def add(x, y): return x + y # 這裏返回一個partial對象 newadd = partial(add, y=5) print(newadd) # functools.partial(<function add at 0x1005a21e0>, y=5) # 除去魔術方法,一個partial對象包含三個屬性 # - func,指向partial函數傳遞的函數對象 # - args,收集partial函數傳遞的位置參數 # - keywords,收集partial函數傳遞的關鍵字參數 print(newadd(7)) # 12 print(newadd(7, y=6)) # 13 print(newadd(y=10, x=4)) # 14 # print(newadd(4, 5)) # 這裏因爲y已經固定爲關鍵字參數y=5,只能經過關鍵字傳參覆蓋,實際上這裏的y是keyword-only參數,經過函數簽名能夠看到
固定位置參數xide
newadd = partial(add, 4) print(newadd(5)) # 9 # print(newadd(x=1, y=2)) # 不能這樣傳參,這裏因爲x已經固定爲位置參數4,不能經過關鍵字參數覆蓋
同時固定位置參數x和y函數
# 爲了能打印出多出來的位置參數,這裏手動傳一個*args,不過被partial處理後這裏只能收集到被固定x,y以外的參數 def add(x, y, *args): print(args) return x + y # 實際上,不顯式傳遞可變參數,partial也會處理全部傳遞進來的參數,官方說法以下: # If more arguments are supplied to the call, they are appended to args. # If additional keyword arguments are supplied, they extend and override keywords. # 多出來的位置參數會被追加到partial的args屬性中 # 多出來的關鍵字參數會更新到partial的keywords屬性中 newadd = partial(add, 1, 3, 6, 5) print(newadd(7)) # (6, 5, 7) # 4 print(newadd(7,10)) # (6, 5, 7, 10) # 4 print(newadd()) # (6, 5) # 4 # print(newadd(9, 10, y=20, x=26)) # 這裏一樣會拋出異常,緣由再也不贅述
參考:
https://docs.python.org/3/library/functools.html#functools.partialcode