Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Functools -- partial

✅ 1. partial 是什么?

partial 是 Python 函数式编程的核心工具之一:

from functools import partial

它的作用是:

预先为一个函数绑定部分参数,返回一个新的函数。

这叫 偏函数(partial function)。

🟩 2. 最简单示例(立即理解)

from functools import partial

def power(base, exponent):
    return base ** exponent

square = partial(power, exponent=2)
cube   = partial(power, exponent=3)

print(square(5))  # 25
print(cube(5))    # 125
  • square、cube 都是 partial 生成的新函数。
  • 它们已经绑定好了 exponent 参数。

🟦 3. partial 能解决什么问题?

⭐ 作用总结

  • 给函数预填默认参数
  • 函数定制化
  • 方便函数作为回调传递
  • 用于 map/filter/reduce 更优雅
  • 用于 asyncio / thread pool 更方便
  • 让代码更短、更可读

🟧 4. 真实场景示例(更实用)

场景 1:requests 带默认 headers

import requests
from functools import partial

get_json = partial(requests.get, headers={
    "User-Agent": "Mozilla/5.0"
})

resp = get_json("https://api.example.com/data")
print(resp.json())

以后不需要每次都写 headers。

场景 2:log 封装

from functools import partial
from loguru import logger

info = partial(logger.log, "INFO")
debug = partial(logger.log, "DEBUG")

info("程序开始")
debug("变量 x=10")

场景 3:文件读写带默认编码(常用!)

open_utf8 = partial(open, encoding="utf-8")

with open_utf8("text.txt") as f:
    print(f.read())

比每次写 open(..., encoding="utf-8") 更优雅。

场景 4:functools.partial 与 map 结合

def multiply(a, b):
    return a * b

double = partial(multiply, 2)

print(list(map(double, [1, 2, 3])))

输出:

[2, 4, 6]

场景 5:回调函数(如 Tkinter、GUI)

button_click = partial(on_click, id=123)

GUI 事件回调只能放一个函数参数,partial 很好用。

场景 6:多线程 pool 更方便

from concurrent.futures import ThreadPoolExecutor
from functools import partial

def download(url, folder):
    ...

download_to_tmp = partial(download, folder="/tmp")

with ThreadPoolExecutor() as p:
    p.map(download_to_tmp, urls)

避免 lambda,代码更清晰。

🟩 5. partial 的完整语法

partial(func, *args, **kwargs)

关键点:

  • args 会填到左边的参数
  • kwargs 会填到函数对应的关键字参数
  • 剩余参数仍可传入

示例:

def test(a, b, c):
    print(a, b, c)

f = partial(test, 1, c=3)
f(2)    # a=1, b=2, c=3

🔥 6. 高级特性:partial 还能修改属性

f = partial(pow, exponent=2)
f.__name__ = "square"

🟦 7. partial 与 lambda 的对比

| 功能 | partial | lambda | | 可读性 | ⭐⭐⭐⭐⭐ | ⭐⭐ | | 性能 | ⭐⭐⭐⭐ | ⭐⭐⭐ | | 可调试性 | ⭐⭐⭐⭐⭐ | ⭐ | | 代码简洁 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | | 支持绑定参数 | ✅ | ✅ | | 支持绑定关键字参数 | ✅ | ✅ | | 适合回调 | ✅ | ⚠️ 一般 |

partial 推荐优先使用。

🟧 8. 构造偏函数(官方例子)

from functools import partial

basetwo = partial(int, base=2)

print(basetwo('10010'))  # 18

🟥 9. partial 中的参数覆盖规则(很重要)

def func(a, b, c):
    print(a, b, c)

f = partial(func, 1, b=2)
f(c=3)      # OK

如果传入重复参数:

f(b=5)  # ❌ TypeError

因为 b 已经在 partial 中绑定过了。

🟦 10. 一屏速查表(终极总结)

from functools import partial

partial(func, *args, **kwargs)

用途:

  • 函数预绑定参数
  • 让函数变简单
  • GUI、回调、线程池
  • requests、open、logger 封装

优势:

  • 可读性更高优于 lambda
  • 参数依然可扩展
  • 适配旧代码和回调