首页 > 解决方案 > 使作为参数给出的函数真正可见

问题描述

我正在编写的函数将函数列表作为参数。如何将列表中的函数绑定到外部函数命名空间中的名称?为了澄清,这应该是可执行的:

def fun1(x):
    return x+1

def fun2(x):
    return x-1

def outer(funcs, execstr):
    #???
    exec(execstr)    

outer([fun1, fun2], "print(fun1(x) + fun2(x))")

我认为我可以找到一个在外部函数中执行 funcs 代码的 hacky 解决方法,但这似乎非常浪费。有没有更好的方法?

补充:这是一个程序合成练习:我可以合成一个带有python函数F定义的字符串。我想在某个包装函数的上下文中评估该函数,该函数的符号表填充了F代码中所有缺失的细节。下面的代码工作正常,因为 fun1 和 fun2 在外部范围内。

def outer():

    def fun1(x):
        return x+1

    def fun2(x):
        return x-1

    exec("print(fun1(2) + fun2(3))")

outer()

所以,我想我想添加到外部条目的 locals() 字典中,比如 'fun1': ....

在阅读有关 exec 的更多信息后进行编辑:

def fun1(x):
    return x+1

def fun2(x):
    return x-1

def outer(f1,f2):

    lf = {}
    lf['fun1'] = f1
    lf['fun2'] = f2    

    exec("print(fun1(2) + fun2(3))", lf)

outer(fun1, fun2)

好的,我了解了它的工作原理。这为我解决了。

标签: python

解决方案


我想我并不完全理解整个问题以及您对此的打算,但我发现尝试做类似的事情可能很有趣。

回答(我相信是)你的问题,我认为不可能将函数作为参数传递给“动态”调用它们(据我在 python 中所知)。但是您可以动态创建一个调用这些函数的程序。

首先,创建包含您将使用的函数和变量的“主”脚本(我称之为“scratch.py​​”)。在该脚本中,编写一个函数,该函数将根据传递给它的参数编写另一个脚本:

x = 2

def fun1(x):
    return x+1

def fun2(x):
    return x-1

def outer(execstr):
    f = open('test.py', 'w')
    f.write("from scratch import *\n")
    f.write("def exec_code():\n")
    f.write("\t" + execstr + "\n")
    f.write("exec_code()\n")
    f.close()

def main():
    outer("print(fun1(x) + fun2(x))")
    import test

if __name__ == "__main__":
    main()

该脚本将生成第二个“动态”脚本(称为 test.py),该脚本导入“主”脚本(scratch)以便能够使用函数和变量,并在创建后在之前的脚本中导入(并执行) . 它看起来像这样:

from scratch import *
def exec_code():
    print(fun1(x) + fun2(x))
exec_code()

输出:

4

...没用,但很有趣!


推荐阅读