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

时间:2016-03-31 15:01:22

标签: python eval string-literals

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

我的目标是取代它:

>>> import logging
>>> eval('logging.DEBUG')
10

用更安全的替代品,这个:

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

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

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

  

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

     

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

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

1 个答案:

答案 0 :(得分:4)

根据您在评论中提供的背景,我建议您不要这样做:

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

我的建议是使用地图:

log_levels = { 'DEBUG': logging.DEBUG, ... }

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

real_level = log_levels[log_level]

通过这种方式,您可以轻松接受real_level = log_levels[log_level.upper()]的案例错误,如果配置文件中存在意外值,您只会获得KeyError例外,不会有不必要的评估风险。