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

Assistance with Python's ast.literal_eval('a_string')

我一直在尝试让 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>

但后者不起作用(至少不是我使用它的方式)。请注意,我也尝试了 triple-quotedraw-string 变体。

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

Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None.

This can be used for safely evaluating strings containing Python values from untrusted sources without the need to parse the values oneself. It is not capable of evaluating arbitrarily complex expressions, for example involving operators or indexing.

感谢任何帮助。 =:) 提前谢谢你!

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

  • 你不能使用 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 异常,没有不需要的评估的风险。