partial函数从Python 2.5开始在标准库中出现(functools模块),旨在实现柯里化模式和对函数参数的部分应用。partialmethod则在Python 3.4中出现,目的是在类方法中实现类似的应用。
在实际项目中,经常会遇到将部分参数固定在函数中的问题,以便获得一个带有“记住”某些参数值的新函数。这对回调、参数传递模板,或提高代码可读性特别方便,尤其是在函数式编程和使用期望特定样式函数的API时。
partial函数返回一个新的函数对象,其中某些传递的参数或关键字参数被“硬编码”(固定)。partialmethod对类的方法实现了同样的思路,正确支持self/cls的传递机制。
代码示例:
from functools import partial, partialmethod def power(base, exponent): return base ** exponent # 固定指数=2 square = partial(power, exponent=2) print(square(5)) # 25 class Math: def power(self, base, exponent): return base ** exponent square = partialmethod(power, exponent=2) m = Math() print(m.square(5)) # 25
关键特点:
可以使用partial为类方法获得与partialmethod类似的结果吗?
不可以,partial不能正确处理self/cls,当应用于类方法时不会按预期工作:self不会自动传递。
class C: def m(self, x, y): return x + y wrong = partial(m, y=2) # 错误!
调用c.wrong(5)将引发TypeError,因为self不会自动传递。
通过partial创建的对象是函数吗?
是的,partial的结果是一个表现得像函数的对象,支持调用、名称、文档字符串等,但它不是普通函数,而是实现了__call__协议的partial类的对象。
from functools import partial f = partial(pow, 2) print(type(f)) # <class 'functools.partial'>
partial是否与函数的默认参数一起工作?
是的,partial可以“重写”内部函数中的默认值;如果传递给partial的参数优先于函数本身中的默认值。然而,重要的是不要重复值,否则会发生错误。
开发人员将partial应用于类方法而不是partialmethod:
class MyClass: def f(self, x, y): ... squared = partial(f, y=2) ... obj = MyClass() obj.squared(5) # TypeError: missing 1 required positional argument: 'self'
优点:
缺点:
相反使用partialmethod:
from functools import partialmethod class MyClass: def f(self, x, y): return x + y squared = partialmethod(f, y=2) obj = MyClass() print(obj.squared(5)) # 7
优点:
缺点: