Functools -- partialmethod
partialmethod 专门用于 类中的方法,它用于:
预先绑定方法的一部分参数,生成一个新的 class method。
类似于 partial(偏函数),但:
⭐ partial 用于函数
⭐ partialmethod 用于类的方法
from functools import partialmethod
class Logger:
def log(self, level, msg):
print(f"[{level}] {msg}")
info = partialmethod(log, "INFO")
error = partialmethod(log, "ERROR")
l = Logger()
l.info("启动完成")
l.error("出错了")
输出:
[INFO] 启动完成
[ERROR] 出错了
👉 info() 和 error() 实际上是 log() 绑定参数后的方法。
如果一个类中:
- 某些方法参数几乎一样
- 需要根据不同模式定制方法
- 需要减少重复代码
- 类内大量“模板方法”
- 想优雅复用方法逻辑
partialmethod 能让代码更简洁。
partialmethod(func, *pre_args, **pre_kwargs) 会:
- 生成一个方法对象 (callable)
- 调用时自动把预设参数应用在 后面实际调用的方法中
- self 会被自动传入第一个参数
例如:
info = partialmethod(log, "INFO")
实际上相当于:
def info(self, msg):
return self.log("INFO", msg)
| 功能 | partial | partialmethod | | 用于普通函数 | ✅ | ❌ | | 用于类方法 | ⚠️ 可用但不优雅 | ✅ 专门设计 | | 自动绑定 self | ❌ 需要手动处理 | ✅ 自动绑定 self | | 语法可读性 | 一般 | 更清晰 | | 常用场景 | map / callbacks | 类中创建定制方法 |
partial + 类:
class A:
m = partial(f, x)
⚠️ 这种方式 self 不会自动传入,会出错。
下面是最常见的工程用法:
class Log:
def log(self, level, msg):
print(f"[{level}] {msg}")
info = partialmethod(log, "INFO")
debug = partialmethod(log, "DEBUG")
error = partialmethod(log, "ERROR")
避免写重复代码:
log.error("数据库连接失败")
class FSM:
def transition(self, event, *args):
print(f"转移状态: {event}, args={args}")
start = partialmethod(transition, "start")
stop = partialmethod(transition, "stop")
reset = partialmethod(transition, "reset")
class APIClient:
def request(self, method, path, **kwargs):
print(f"{method} {path}", kwargs)
get = partialmethod(request, "GET")
post = partialmethod(request, "POST")
put = partialmethod(request, "PUT")
使用:
api = APIClient()
api.get("/users")
api.post("/users", json={"a": 1})
class DB:
def query(self, table, where=None):
...
query_users = partialmethod(query, "users")
query_logs = partialmethod(query, "logs")
partialmethod(func, /, *args, **kwargs)
- args -> 固定位置参数
- kwargs -> 固定关键字参数
- self 在调用时自动注入
class Calculator:
def calc(self, x, y, op):
if op == "+":
return x + y
else:
return x - y
add = partialmethod(calc, op="+")
sub = partialmethod(calc, op="-")
c = Calculator()
print(c.add(1, 2)) # 3
print(c.sub(5, 3)) # 2
debug_info = partialmethod(Logger.info, "[DEBUG]")
❌ 不能用于 staticmethod / classmethod 上
例如:
class A:
@staticmethod
def f(x): pass
g = partialmethod(f, 1) # ❌ 不能这样用
partialmethod 需要“绑定 self”。
✅ 要绑定类方法,必须保持目标方法是实例方法。
from functools import partialmethod
class C:
def func(self, x, y):
...
f = partialmethod(func, 100) # 等效于 func(self, 100, y)
用途:
- 创建多个参数略有不同的方法
- 日志系统
- HTTP Client
- 状态机
- ORM 封装
优点:
- 自动传 self
- 可读性强
- 代码复用率高