从文本文件中读取 python 函数并将其分配给变量

Read python function from a text file and assign it to variable

我有一个包含 Python 函数的文本文件,如下所示:

a.txt

def func():
    var = 5
    return var

然后我在 Python 脚本中读取了这个文件:

b.py

python_file = open("a.txt").read()

现在我想将 a.txt 文件的函数分配给一个变量,而不用担心函数名称并执行它。我试过这样的事情:

python_file = open("a.txt").read()
b = exec(python_file)
b()

但是没用,我也试了execfile

exec输入字符串后,您可以直接调用 func,因为它已添加到您当前的命名空间中:

>>> exec("""def func():
    var = 5  # note that the semicolons are redundant and unpythonic
    return var""")
>>> func()
5

Per its documentation exec 实际上 return 什么都没有,所以没有必要分配例如foo = exec(...).


要查看正在执行的代码中本地定义的名称,请将空字典作为 locals 参数传递给 exec

>>> ns = {}
>>> exec("""def func():
    var = 5
    return var""", globals(), ns)
>>> ns
{'func': <function func at 0x0315F540>}

然后您可以像往常一样分配函数并调用它:

>>> b, = ns.values()  # this will only work if only one name was defined
>>> b()
5

在提供我的解决方案之前,我强烈警告不要这样做,除非您确定 a.txt.

中没有恶意代码

我的解决方案使用 execfile 函数加载文本文件和 return 第一个对象(可以是变量或函数):

def load_function(filename):
    """ Assume that filename contains only 1 function """
    global_var = dict()
    execfile(filename, global_var)
    del global_var['__builtins__']
    return next(global_var.itervalues())

# Use it
myfunction = load_function('a.txt')
print myfunction()

更新

要更加小心,像下面这样修改 return 行,使其跳过变量(但是它不能跳过 class 声明)。

    return next(f for f in global_var.itervalues() if callable(f))

更新 2

感谢 johnsharpe 指出 Python 中没有 execfile 3. 这是一个修改后的解决方案,它使用 exec 代替。这次,该函数应该在 "local" 范围内找到。

def load_function(filename):
    """ Assume that filename contains only 1 function """
    with open(filename) as f:
        file_contents = f.read()
        global_var = dict()
        local_var = dict()
        exec file_contents in global_var, local_var
        return next(f for f in local_var.itervalues() if callable(f))

# Use it
myfunction = load_function('a.txt')
print myfunction()