functools.partial 可「凍結」函式部分位置/關鍵字參數,產生新的可呼叫物件(偏函式),常用於回調函式參數預設、API 客戶端封裝、事件處理器綁定參數等場景。
import functools
def foo(a, b=0):
print(a + b)
foo(1) # 1 (使用預設 b=0)
foo(1, 1) # 2 (覆寫 b=1)
# 修改 b 的預設值為 5
foo1 = functools.partial(foo, b=5)
foo1(1) # 6
# 給原本無預設值的 a 設定預設值 10
foo2 = functools.partial(foo, a=10)
foo2() # 10
foo2(b=3) # 13
>>> foo2.func
>>> foo2.args
()
>>> foo2.keywords
{'a': 10}
func:原始函式args:預先綁定的位置參數元組keywords:預先綁定的關鍵字參數字典>>> foo2.__doc__
Traceback (most recent call last):
AttributeError: 'functools.partial' object has no attribute '__doc__'
>>> functools.update_wrapper(foo2, foo)
>>> foo2.__doc__
'int add'
將原函式的 __name__, __doc__, __module__, __annotations__ 等複製到 partial 物件,利於除錯與文件產生工具。
import requests
from functools import partial
base_get = partial(requests.get, timeout=5, headers={'User-Agent': 'MyBot/1.0'})
# 之後呼叫 base_get(url) 即自帶超時與 UA
inspect.isfunction(foo2) 為 False,裝飾器鏈需留意。args 之後。functools.singledispatch 實現更靈活的多型分派。善用 partial 可減少重複參數傳遞、提升程式碼可讀性與可測試性。