如何动态创建非可变参数函数(没有 eval 或类似函数)?

Wrzlprmft

概述

在运行时的某个时间点,我想创建一个函数,它完全采用给定数量的参数(仅在运行时已知)。正是在这里意味着这不能是一个可变参数函数。有没有办法在不诉诸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. 因此,我需要概括上述内容。

到目前为止我发现了什么

  • 我使用evalexec或类似)实现了我想要的

    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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章