偏函數

偏函數(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

相關文章
相關標籤/搜索