协助 Python 的 ast.literal_eval('a_string')

NYC*_*yes 5 python eval string-literals

我一直在尝试让 Python3s ast.literal_eval () 函数工作(在交互式 Python 会话中)但是 - 我阅读了它的文档描述 - 我不能。

我的目标是替换这个:

>>> import logging
>>> eval('logging.DEBUG')
10
Run Code Online (Sandbox Code Playgroud)

有了更安全的选择,这个:

>>> import logging, ast
>>> ast.literal_eval('logging.DEBUG')
Traceback (most recent call last):
...
ValueError: malformed node or string: <_ast.Attribute object at 0x7f1ccc55eeb8>
Run Code Online (Sandbox Code Playgroud)

但后者不起作用(至少不是我如何使用它)。请注意,我也尝试了三引号原始字符串变体。

我相信我只是在这里遗漏了一个细微差别(例如,它可能不喜欢评估模块中的常量)。来自关于ast.literal_eval ()的 Python-3 文档:

安全地计算包含 Python 文字或容器显示的表达式节点或字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、字节、数字、元组、列表、字典、集合、布尔值和无。

这可用于安全地评估包含来自不受信任来源的 Python 值的字符串,而无需自己解析这些值。它不能评估任意复杂的表达式,例如涉及运算符或索引。

任何帮助表示赞赏。=:) 提前谢谢你!

Ser*_*sta 4

根据您在评论中给出的上下文,我建议您不要这样做:

  • 你不能使用,ast.literal_eval因为logging.Debug它不是一个文字:你从模块中询问一个值,这可能会产生任意的副作用
  • 您不应该将 eval 用于从外部文件读取的值。

我的建议是使用地图:

log_levels = { 'DEBUG': logging.DEBUG, ... }
Run Code Online (Sandbox Code Playgroud)

当您稍后log_level从配置文件中读取(例如调试)时,您只需执行以下操作:

real_level = log_levels[log_level]
Run Code Online (Sandbox Code Playgroud)

这样您就可以轻松接受大小写错误real_level = log_levels[log_level.upper()],并且如果配置文件中存在意外值,您只会得到一个KeyError异常,而不会出现不必要的评估风险。