【发布时间】:2010-06-10 08:02:00
【问题描述】:
我很好奇是否可以采用几个条件函数并创建一个检查所有条件的函数(例如,生成器采用过程来迭代一系列并创建迭代器的方式)。
基本用例是当您有大量条件参数(例如“max_a”、“min_a”、“max_b”、“min_b”等)时,其中许多可能是空白的。它们都将被传递给这个“函数创建”函数,然后该函数将返回一个检查它们的函数。下面是一个天真的方式的例子:
def combining_function(max_a, min_a, max_b, min_b, ...):
f_array = []
if max_a is not None:
f_array.append( lambda x: x.a < max_a )
if min_a is not None:
f_array.append( lambda x: x.a > min_a )
...
return lambda x: all( [ f(x) for f in f_array ] )
我想知道的是,实现上述目标的最有效方法是什么?似乎为 f_array 中的每个函数执行函数调用会产生相当大的开销,但也许我正在进行过早/不必要的优化。无论如何,我很想看看是否有其他人遇到过这样的用例以及他们是如何进行的。
另外,如果这在 Python 中是不可能的,那么在其他(可能更实用的)语言中是否可能?
编辑:看起来共识解决方案是组成一个包含完整条件集合的字符串,然后使用 exec 或 eval 生成单个函数。 @doublep 建议这是相当骇人听闻的。对这有多糟糕有任何想法吗?在编写这样的解决方案可以被认为是安全的函数时,是否可以足够仔细地检查参数?毕竟,无论需要什么严格的检查,都只需要执行一次,而更快的组合条件的好处可以通过大量的调用来累积。人们是在部署场景中使用这样的东西还是这主要是一种可以玩弄的技术?
【问题讨论】:
-
你所有的条件参数都是最大/最小对吗?这绝对是可能的,但如何去做取决于你将要进行什么样的测试。
-
删除对
all()的调用中的列表,即只是all (f(x) for f in f_array)。如果任何f产生错误值,这将提前停止。 -
@doublep:这只适用于最近的python。有些人仍然必须使用过时的版本 ;-)
-
@liori:好的,你说得有道理。然后放弃 lambda 并返回执行
for f in f_array: ...的本地函数定义会更有效。当前版本永远不会提前停止并创建一个不需要的列表对象。 -
规格不清楚。似乎首先您要检查
min_a < x.a < max_a,但对于下一对检查其他属性,大概是x.b?而且由于 args 不带有它们的名字,因此无法知道下一个要检查的参数是什么!
标签: python functional-programming