Python Eval 执行环境

0 投票
1 回答
1396 浏览
提问于 2025-04-15 19:49

我不太明白,eval 或 exec 语句是在什么环境下执行的。你可以把全局和局部的作用域传给它们,但我不太理解这是什么意思。Python 是不是为它们创建了一个匿名模块?如果是这样,全局和局部的作用域又有什么不同呢?

它的运行方式是不是像一个匿名函数?如果是这样的话,全局和局部的作用域对我来说就更有意义了。不过,你还需要用 global var 来防止 Python 在赋值时创建一个局部变量吗?

这里有一些代码,展示我实际上想做的事情。

# module level vars
result = ''

allowed_builtins = {"__builtins__":{'int':int, 'str':str, 'range':range, 'dir':dir,
                                    'zip':zip
},
                    "result":result}

在类里面

def _exec(self, answer, function_name, input):
    global result
    exec_string = answer + '\n'
    exec_string += 'global result; result = %s(%s)' % (function_name, input)
    exec exec_string in allowed_builtins, {}

    return result

我希望在 eval/exec 的作用域内能够设置我作用域里的变量 result。

1 个回答

2

“本地”字典是用来存放在execeval执行过程中所有名称的地方;而“全局”字典则是在本地字典找不到名称时用来查找的地方。不过,除非你在执行的代码中包含了global语句,否则名称不会在全局字典中被设置。

无论是eval还是exec,都不会自动创建模块对象,也不会创建函数对象,无论是匿名函数还是其他类型的函数(当然,除非你执行的代码中有def这样的语句)。

编辑:举个例子,假设_exec是一个独立的函数,因为提问者没有给出它可能所在的class,在最后加上:

print 'one: %r' % _exec(None, '"foo"', 'range', 7)
print 'two: %r' % allowed_builtins['result']

你会看到这样的输出:

one: ''
two: [0, 1, 2, 3, 4, 5, 6]

当前模块中的__dict__里的result当然不会受到影响(怎么可能会受到影响呢,因为这个字典从来没有传递给相关的exec?)-- 受影响的当然是allowed_builtins字典,因为它是作为“全局字典”传递的,而在被exec执行的字符串中确实有global语句!

撰写回答