jde*_*esa 2 python built-in apply higher-order-functions python-3.x
望着这个问题,我意识到,这是一种很难使用multiprocessing的Pool.map,如果你想在运行并行的功能列表:
from multiprocessing import Pool
def my_fun1(): return 1
def my_fun2(): return 2
def my_fun3(): return 3
with Pool(3) as p:
one, two, three = p.map(lambda f: f(), [my_fun1, my_fun2, my_fun3])
Run Code Online (Sandbox Code Playgroud)
我并不是说它完全是神秘的,但我想我期待一些传统的名称,即使只是在内部functools或某些内容,类似于apply/ call在JavaScript中(是的,我知道当时这些函数的JavaScript没有lambda)定义,不,我不是说JavaScript是一种示例性的编程语言,只是一个例子).事实上,我绝对认为应该存在这样的事情operator,但是(除非我的眼睛欺骗了我)似乎缺席了.我读到,在身份功能的情况下,分辨率是让人们定义他们自己的琐碎功能,在这种情况下我理解得更好,因为你可能想要几个不同的变化,但这个感觉就像一个缺失的位对我来说.
编辑:正如评论中所指出的,Python 2曾经有过这个apply功能.
首先,让我们来看看实际问题.
对于2.3以上的任何Python,你可以简单地写出不仅仅是你的无参数apply,而是一个完美的转发apply,作为一个单行,如2.x文档中所述apply:
使用
apply()相当于function(*args, **keywords)
换一种说法:
def apply(function, *args, **keywords):
return function(*args, **keywords)
Run Code Online (Sandbox Code Playgroud)
...或者,作为内联lambda:
lambda f, *a, **k: f(*a, **kw)
Run Code Online (Sandbox Code Playgroud)
当然,C实现速度要快一些,但这几乎从来都不相关.1
如果你不止一次地使用它,我认为定义函数不符合并按名称重用它可能更清晰,但是lamdba版本很简单而且非常明显(对于你的no-args来说更是如此)用例),我无法想象有人抱怨它.
另外,请注意,这实际上比identity您理解您正在做的事情更为微不足道,而不是更少.有了identity,你应该用多个参数(或关键字参数)返回的内容很模糊,所以你必须决定你想要的行为; 因为apple,只有一个明显的答案,而且几乎不可能出错.
至于历史:
像JavaScript一样,Python最初没有lambda.很难为2.6之前的版本挖掘可链接的文档,并且很难在2.3之前找到它们,但我认为lambda在1.5中添加它们,并且最终达到了它可以用于2.2左右的完美转发的程度.在此之前,文档建议apply用于转发,但在此之后,建议使用的文档lambda代替apply.事实上,不再有任何推荐使用apply.
所以在2.3中,该函数已被弃用.2
在导致3.0的Python-3000讨论期间,Guido建议所有"函数式编程"函数除了可能 map并且filter是不必要的.3其他人为reduce和partial.4但案件的一个重要部分是,他们实际上是不平凡的写(在全一般形式),并且容易出错.事实并非如此apply.同时,人们也能找到相关的用途reduce和partial在真实世界的代码库,但唯一的用途apply任何人都可以找到比较旧预2.3代码.事实上,它是如此罕见,甚至不值得使2to3工具转换调用apply.
PEP 3100总结了删除它的最终理由:
apply():f(*args, **kw)改用[2]
该脚注链接到Guido的一篇名为"Python Regrets"的文章,该文章现在是404链接.但是,随附的PowerPoint演示文稿仍然可用,或者您可以查看他为其编写的演示文稿的HTML翻页.但它真正说的是同一个单行,而IIRC,唯一进一步的讨论是"我们已经在2.3中有效地摆脱了它."
1.在大多数必须应用函数的惯用Python代码中,该函数内部的工作非常繁重.当然,在你的情况下,调用函数(pickling参数并将它们传递给管道)的开销更大.重要的一个例子是当你正在进行"Haskell风格的函数式编程"而不是"Lisp风格"时 - 即很少有函数定义,以及通过转换函数和组合结果而产生的大量函数.但是在Python中已经非常缓慢(并且堆栈繁重),这不是一件合理的事情.(平面使用装饰器来应用包装或三个工作很好,但是一个潜在的无限包装链会破坏你的性能.)
2.正式的弃用机制尚不存在,因此它只是转移到文档中的"非必要的内置函数"部分.但是,从2.3文档中可以看出,它从2.3开始被追溯到被弃用.
圭多最初想要摆脱他们; 正如你在"遗憾"翻书中看到的那样,列表理解可以更好地完成同样的工作.但是itertools.imap,代替map手段促进它可以变得懒惰,就像新的一样zip,因此比理解更好.我不确定为什么Guido不只是用生成器表达式做出相同的参数.
我不确定圭多本人是否有信心reduce,但整个核心开发者都是.
| 归档时间: |
|
| 查看次数: |
82 次 |
| 最近记录: |