【问题标题】:Why does ast.literal_eval() evaluate these two dictionaries differently?为什么 ast.literal_eval() 对这两个字典的评估不同?
【发布时间】:2020-10-31 02:56:13
【问题描述】:

我的问题是为什么以有效方式创建的字典“a”与字典“b”不同。

在下面的代码中,您会看到一个简单的字典“a”,我想用它来检查

a = ast.literal_eval(a)

奇怪的是,“a”似乎不是字典或任何 Python 语法认为有效的东西,因为 ast.literal_eval(a) 会引发异常:

失败:错误的节点或字符串:{':': 5}

字典操作 a.keys() 按预期返回 ':'。

更奇怪的是,当用“转换”原始字典时

b = str(a)

字典 b 实际上在第二个 try 语句中被评估为字典。

import ast

a = {}
a[":"] = 5

b = str(a)

print(a)
print(b)

try:
    a = ast.literal_eval(a)
    print(type(a))
except Exception as e:
    print(f'a failed: {e}')

try:
    b = ast.literal_eval(b)
    print(type(b))
except Exception as e:
    print(f'b failed: {e}')

输出:

{':': 5}
{':': 5}
a failed: malformed node or string: {':': 5}
<class 'dict'>

【问题讨论】:

  • 是什么让您认为您可以将dict 传递给literal_eval?它的重点是将字符串转换为 Python 对象,有点像 str(x) 的反面。
  • 将字典传递给literal_eval 有什么意义?您希望输出是什么?
  • 我希望 literal_eval() 检查传递的字符串或节点是否对 python 语法有效。
  • @ZackDev 但是你的字典既不是节点也不是字符串...

标签: python-3.x dictionary abstract-syntax-tree


【解决方案1】:

ast.literal_eval 适用于字符串或 AST 节点,而不是字典。

来自the diocumentation

ast.literal_eval(node_or_string)

安全地评估包含 Python 文字或容器显示的 表达式节点字符串

所以 dictionary a 确实是一个“格式错误的节点或字符串”,因为它们都不是。

当您说“字典 b 实际上在第二个try-statement 中被评估为字典”时,这并不完全正确,因为b = str(a) 使b 成为字符串。因此,b 是字典的字符串表示形式,因此可以按预期工作。

【讨论】:

  • 好的,谢谢。所以字典既不是表达式节点也不是字符串。但是为什么 type(b) 说它是 类型呢?
  • 好吧,所以 str(b) 把它变成了一个字符串表示,而 b = ast.literal_eval(b) 又把它变成了一个字典,因此 type(b) 说它是一个字典结束...感谢@JohnZwink、DeepSpace 和 ForceBru
  • @ZackDev,是的,没错! str(thing) 将 Python 对象转换为其字符串表示,ask.literal_eval 将某些类型的字符串表示转换为 Python 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 2015-03-18
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多