说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
partial 函数允许我们复刻函数的某些参数并生成新函数。函数在执行时,要带上所有必要的参数进行调用。但是,有时参数可以在函数被调用之前提前获知。这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调用。简单说就是局部套用一个函数,让广泛功能的函数简单化、单一化。这是一个 柯里化 过程。在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。
简单说 partial 把某个函数的某个参数固定,从而构造出一个新的函数来。返回的这个新函数对象是 partial 对象,下文有介绍。
在一些情况下, 我们在设计 Python 函数的时候, 会给它设定非常丰富的功能, 这样我们就可以定义一个非常强大的函数。 与此同时带来的问题是使用上的不方便, 因为有可能我们需要传递非常多的参数才能换成我们想要的功能。这时候 partial 函数就可以让我们在这个强大的函数中派生出对应的具体功能。
在计算机科学中,柯里化(英语:Currying),又译为科里化、卡瑞化、或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。这个技术由克里斯托弗·斯特雷奇以逻辑学家哈斯凯尔·加里命名的,尽管它是Moses Schönfinkel和戈特洛布·弗雷格发明的。
例如,传入百、十、个位数字生成数字:
from functools import partial
# 常规函数
def add(a, b, c):
return 100 * a + 10 * b + c
# b=1,c=2 的部分函数
add_part = partial(add, c = 2, b = 1)
# 调用 partial 函数
add_part(3)
# 312
例如,我们有加法函数(实际上我们有 sum,不需要它),我们可以将它派生出不同的加法函数:
from functools import partial
def add(a,b):
return a + b
def add2number(x,y,z):
return x + y + z
# a 固定值为 2
add2 = partial(add,2)
add2(1)
# 3
# 将 x 固定为 1,y 值固定为 2
add3 = partial(partial(add2number,1), 2)
add3(1)
# 4
完整语法为:functools.partial(func, /, *args, **keywords)
,返回一个新的 partial 对象(部分对象,见下文),又称偏函数,主要用途是减少可调用对象的参数个数,当被调用时其行为类似于 func 附带位置参数 args 和关键字参数 keywords 被调用。 如果为调用提供了更多的参数,它们会被附加到 args。 如果提供了额外的关键字参数,它们会扩展并重载 keywords。 这个函数是使用 C 而不是 Python 实现的,大致等价于:
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
partial() 会被“冻结了”一部分函数参数和/或关键字的部分函数应用所使用,从而得到一个具有简化签名的新对象。 例如,partial() 可用来创建一个行为类似于 int() 函数的可调用对象,其中 base 参数默认为二:
from functools import partial
basetwo = partial(int, base=2)
basetwo.__doc__ = 'Convert base 2 string to an int.'
basetwo('10010')
# 18
在类中如果想实现 partial 类似的派生方法的话,可以使用 functools.partialmethod 方法,如:
import functools
class RGB(object):
def __init__(self, red, blue, green):
super(RGB, self).__init__()
self._red = red
self._blue = blue
self._green = green
def _color(self, type):
return getattr(self, type)
red = functools.partialmethod(_color, type='_red')
blue = functools.partialmethod(_color, type='_blue')
green = functools.partialmethod(_color, type='_green')
partial 对象是由 partial() 创建的可调用对象。 它们具有三个只读属性:
partial 对象与 function 对象的类似之处在于它们都是可调用、可弱引用的对象并可拥有属性。 但两者也存在一些重要的区别。 例如前者不会自动创建 __name__
和 __doc__
属性。 而且,在类中定义的 partial 对象的行为类似于静态方法,并且不会在实例属性查找期间转换为绑定方法。
如上例 basetwo 就是一个 partial 对象:
from functools import partial
basetwo = partial(int, base=2)
basetwo
# functools.partial(<class 'int'>, base=2)
basetwo.args
# ()
basetwo.func
# int
basetwo.keywords
# {'base': 2}
偏函数可用于从常规函数派生专用函数,从而帮助我们重用代码。
这个特性类似于C++中的绑定。
Currying 是将一个具有n个参数的函数划分为 n 个具有一个参数的连续函数。部分应用程序是使用一些参数“预填充”函数( 'pre-filling' a function),然后返回参数数量较少的函数。
如果在 Python 类中想定义偏方法,可使用 partialmethod() 偏方法。
更新时间:2022-01-20 18:38:08 标签:python partial 函数