Python中exec和eval的使用

8 投票
8 回答
4559 浏览
提问于 2025-04-16 06:55

我已经明白了 execevalcompile 的作用。但是我不太明白为什么我需要使用它们?我对它们的使用场景不太清楚。

有没有人能给我一些例子,这样我可以更好地理解这些概念?因为现在我只知道这些都是理论。

8 个回答

3

ast 是一个工具,它利用 compile 来从 Python 源代码生成抽象语法树。抽象语法树是一种结构化的表示方式,可以帮助其他模块,比如 pyflakes,来分析和验证 Python 代码的正确性。

def parse(expr, filename='<unknown>', mode='exec'):
    """
    Parse an expression into an AST node.
    Equivalent to compile(expr, filename, mode, PyCF_ONLY_AST).
    """
    return compile(expr, filename, mode, PyCF_ONLY_AST)
4

标准库里有一个很好的例子,教我们怎么使用 execcollections.namedtuple 就是用它来动态创建一个类的。

template = '''class %(typename)s(tuple):
    '%(typename)s(%(argtxt)s)' \n
    __slots__ = () \n
    _fields = %(field_names)r \n
    def __new__(_cls, %(argtxt)s):
        'Create new instance of %(typename)s(%(argtxt)s)'
        return _tuple.__new__(_cls, (%(argtxt)s)) \n
    ...'''

   namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename,
                     OrderedDict=OrderedDict, _property=property, _tuple=tuple)
   try:
       exec template in namespace
   except SyntaxError, e:
       raise SyntaxError(e.message + ':\n' + template)
5

我来举个例子,说明我在什么情况下使用了 eval,并且我觉得这是个不错的选择。

我在写一个简单的软件测试工具,目的是测试学生的作业是否符合要求。我的目标是提供一种简单的配置文件,让它作为测试规范,这样就能避免用编程语言来描述、记录或实现这些基础编程作业的测试用例时遇到的“鸡和蛋”问题。

我把我的工具建立在标准库里的 ConfigParser 上。不过,我希望能够表示任意的 Python 字符串,包括换行符(\n)、制表符(\t),特别是从中读取的任何十六进制编码的 ASCII 字符。

我的解决方案是用 try 包裹一个 parsed_string=eval('''%s''' % cfg_read_item),然后再用 try 来处理同样内容的三重双引号版本("""%s""")。

如果不这样做,我就得写一个 Python 语言解析器,或者找一个现成的解析器,然后想办法把它适配到我的程序里。这样做的风险很小(我并不担心学生提交的代码会欺骗我的解析器,逃出限制,删除我的文件,或者把我的信用卡信息发送到罗马尼亚等等)*

*(部分原因是我是在 Linux 下用一个不受信任的无头用户账户进行测试的)。

正如其他人所说,还有其他情况是你需要根据输入数据构建代码并执行这些代码(元编程)。你总是可以用其他方法完成这些任务。然而,每当这种替代方案需要的编码工作接近于编写一个通用的编程语言解析器/编译器/解释器时,使用 eval 可能是更好的选择。

撰写回答