使用 python 的 eval() 与 ast.literal_eval()

新手上路,请多包涵

我遇到一些代码的情况,其中 eval() 作为可能的解决方案出现。现在我从来没有使用过 eval() 之前,但是,我遇到了很多关于它可能导致的潜在危险的信息。也就是说,我对使用它非常谨慎。

我的情况是我有用户提供的输入:

 datamap = input('Provide some data here: ')

其中 datamap 需要是一本字典。我四处搜索,发现 eval() 可以解决这个问题。我认为我可以在尝试使用数据之前检查输入的类型,这将是一种可行的安全预防措施。

 datamap = eval(input('Provide some data here: ')
if not isinstance(datamap, dict):
    return

我通读了文档,但仍不清楚这是否安全。 eval 是在输入数据后立即评估数据,还是在调用 datamap 变量后评估数据?

ast 模块的 .literal_eval() 是唯一安全的选择吗?

原文由 tijko 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 932
2 个回答

datamap = eval(input('Provide some data here: ')) 意味着您在认为代码不安全 之前 实际评估代码。它会在调用函数后立即评估代码。另见 eval 的危险

ast.literal_eval 如果输入不是有效的 Python 数据类型,则引发异常,因此如果不是,则不会执行代码。

在需要时使用 ast.literal_eval eval 。您通常不应该评估文字 Python 语句。

原文由 Volatility 发布,翻译遵循 CC BY-SA 4.0 许可协议

ast.literal_eval() 只认为 Python 语法的一小部分是有效的:

提供的字符串或节点只能包含以下 Python 文字结构:字符串、字节、数字、元组、列表、字典、集合、布尔值和 None

__import__('os').system('rm -rf /a-path-you-really-care-about') 传递给 ast.literal_eval() 会引发错误,但是 eval() 会很乐意删除您的文件。

由于看起来您只让用户输入普通字典,因此请使用 ast.literal_eval() 。它安全地做你想做的事,仅此而已。

原文由 Blender 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题