柯里化与偏函数
【摘要】 偏函数(partial)和函数柯里化(currying)是函数式编程中常用的技术。有时候我们在复用已有函数时可能需要固定其中的部分参数,这除了可以通过默认值参数来实现之外,还可以使用偏函数。我们定义一个函数:def add(x: int, y=5): return x + y调用 --> add(3, 4)柯里化后:# 柯里化def newadd(x): def wrapper(...
偏函数(partial)和函数柯里化(currying)是函数式编程中常用的技术。有时候我们在复用已有函数时可能需要固定其中的部分参数,这除了可以通过默认值参数来实现之外,还可以使用偏函数。
我们定义一个函数:
def add(x: int, y=5):
return x + y
调用 --> add(3, 4)
柯里化后:
# 柯里化
def newadd(x):
def wrapper(y):
return x + y
return wrapper
调用 --> add(3)(4)
偏函数:
from functools import partial
newadd1 = partial(add, 3)
newadd1(4)
# 7
newadd2 = partial(add, y=5)
newadd2(2)
# 7
newadd2(3, y=4)
# 7
newadd2(3, 5)
# add() got multiple values for argument 'y'
newadd2(3, 5, y=4)
# add() got multiple values for argument 'y'
可能这样看,不太好理解,我们打印下签名
import inspect
inspect.signature(newadd1)
# (y=5)
inspect.signature(newadd2)
# (x: int, *, y=5)
然后 help() 查看一下:
help(partial)
# 有这样一句话:new function with partial application of the given arguments and keywords.
理解就是:对一个函数的部分参数固定,从而返回一个新包装函数,这个函数应该是关于剩余参数的一个函数
查看源码我们也可以看到(3.7后partial用类来实现,原理也是差不多)
# partial 等价
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
ret = func(*args, *fargs, **newkeywords)
return ret
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
偏函数使用非常广泛,比如装饰器 @wraps
def logger(wrapped):
@wraps(wrapped) # wrapper = wraps(wrapped)(wrapper)
def wrapper(*args, **kwargs): # wrapper.__wrapped__ = wrapped
return wrapped(*args, **kwargs)
return wrapper
def logger_equ(wrapped):
def wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
update_wrapper(wrapper, wrapped)
return wrapper
实现使用了partial
# 实例 装饰器中 @wraps 中的实现使用了 partial
def wraps(wrapped,
assigned=WRAPPER_ASSIGNMENTS,
updated=WRAPPER_UPDATES):
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)