functools.partial 提供了哪些您无法通过 lambdas 获得的功能?
没有太多额外的功能(但是,见后文)——而且,可读性是旁观者的眼中。
大多数熟悉函数式编程语言的人(尤其是 Lisp/Scheme 家族的人)似乎都喜欢lambda,我说“大多数”,绝对不是全部,因为 Guido 和我肯定是那些“熟悉”(等)但认为lambda 是 Python 中令人眼花缭乱的异常......
他后悔曾经将它接受到 Python 中,但计划将其从 Python 3 中删除,这是“Python 的故障”之一。
我完全支持他。 (我喜欢lambda in Scheme...虽然它在 Python 中的局限性,以及它的奇怪方式只是不适合其余的语言,让我的皮肤爬行)。
然而,对于成群结队的lambda 爱好者来说并非如此——他们上演了 Python 历史上最接近叛乱的事情之一,直到 Guido 退缩并决定离开 lambda。
functools 的几个可能的添加(以使函数返回常量、标识等)没有发生(以避免显式复制更多 lambda 的功能),尽管 partial 确实保留了(它不是 完全重复,也不是碍眼)。
记住lambda 的主体被限制为表达式,所以它有限制。例如……:
>>> import functools
>>> f = functools.partial(int, base=2)
>>> f.args
()
>>> f.func
<type 'int'>
>>> f.keywords
{'base': 2}
>>>
functools.partial 的返回函数装饰有对内省有用的属性——它包装的函数,以及它在其中修复的位置和命名参数。此外,命名参数可以立即被覆盖(从某种意义上说,“修复”是默认值的设置):
>>> f('23', base=10)
23
所以,如您所见,它定义不像lambda s: int(s, base=2)!-)那么简单
是的,你可以扭曲你的 lambda 来给你一些这个 - 例如,对于关键字覆盖,
>>> f = lambda s, **k: int(s, **dict({'base': 2}, **k))
但我非常希望即使是最热心的lambda-lover 也不会认为这种恐怖比partial 通话更具可读性!-)。 “属性设置”部分更加困难,因为 Python 的 lambda 的“主体是单个表达式”的限制(加上赋值永远不能成为 Python 表达式的一部分的事实)......你最终会“在内部伪造赋值”一个表达式”,通过将列表理解扩展到其设计限制之外......:
>>> f = [f for f in (lambda f: int(s, base=2),)
if setattr(f, 'keywords', {'base': 2}) is None][0]
现在将命名参数的可覆盖性以及三个属性的设置组合成一个表达式,并告诉我 的可读性如何......!