在运行时的某个时间点,我想创建一个函数,它完全采用给定数量的参数(仅在运行时已知)。正是在这里意味着这不能是一个可变参数函数。有没有办法在不诉诸eval
或类似方法将字符串解释为代码的情况下做到这一点?
我想创建一个函数,该函数接受其参数并将它们作为可迭代对象传递给另一个函数。通常,我可以这样做:
my_function = lambda *args: other_function(args)
不幸的是,my_function
将被某些无法正确处理可变参数函数的例程调用¹。但是,my_function
将始终使用相同数量的参数调用n_args
。所以,如果我知道n_args
是 3,我可以使用:
my_function = lambda a,b,c: other_function((a,b,c))
问题是我只n_args
在运行时知道,就在创建my_function
. 因此,我需要概括上述内容。
我使用eval
(exec
或类似)实现了我想要的:
arg_string = ",".join( "arg_%i"%i for i in range(n_args) )
my_function = eval(
"lambda %s: other_function((%s))" % (arg_string,arg_string),
{"other_function":other_function}
)
这样做的缺点是我必须使用eval
,这既丑陋又糟糕。如果您愿意,我的问题是如何在不使用eval
或获取可变参数函数的情况下创建与上述等效的东西。
SymPylambdify
允许我在运行时动态创建具有固定数量参数的函数(在我的上下文中工作),但是查看源代码,它似乎eval
也在幕后使用。
¹ 这是一个用 F2Py 创建的编译例程。我现在无法通过合理的努力来改变这一点。是的,这很可悲,从长远来看,我会尝试解决这个问题或解决这个问题,但现在让我们接受这一点。
创建一个如下所示的函数。您可以编写一个脚本来动态生成代码,以根据需要生成代码,但仍将结果静态保存在普通的 python 文件中,以避免使用 eval/exec。
def function_maker(n_args, other_function):
return [
lambda: other_function(),
lambda arg_0: other_function(arg_0),
lambda arg_0, arg_1: other_function(arg_0, arg_1),
][n_args]
然后按如下方式使用它:
function_maker(2, other_function)(a, b)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句