Dictionary和ast.literal_eval的有趣行为

时间:2014-11-09 22:21:41

标签: python python-2.7 dictionary

我在python REPL中有一个字典:d ={"abc": 1, "def":2}。我从REPL(with open("file","w") as f:)打开了一个文件,并使用f.write(str(d))将字典写入文件。

作为参考,file具有以下内容:"{'abc': 1, 'def': 2}"

然后我运行了一个脚本:

with open("file","r") as g:
    text = g.readlines()[0].rstrip('\n')
    print [text], type(text)
    evaldic = literal_eval(text)
    print [evaldic],type(evaldic)
    evaldic2 = literal_eval(evaldic)
    print [evaldic2],type(evaldic)

给出了以下输出:

['"{\'abc\': 1, \'def\': 2}"'] <type 'str'>
["{'abc': 1, 'def': 2}"] <type 'str'>
[{'abc': 1, 'def': 2}] <type 'dict'>

这表明literal_eval的第一次传递会删除斜线格式并评估输入字符串...是一个字符串?只有literal_eval的第二遍将字符串评估为字典?

为什么呢?这里发生了什么?为什么literal_eval需要将输入字符串评估为字符串,即首先删除格式?为什么我需要做两次评估通过?

1 个答案:

答案 0 :(得分:1)

您已使用repr()

对数据进行了两次编码

>>> d = {'abc': 1, 'def': 2}
>>> repr(d)
"{'abc': 1, 'def': 2}"
>>> repr(repr(d))
'"{\'abc\': 1, \'def\': 2}"'

这是您写入文件的后一个版本;它是一个包含Python字符串表示的字符串,后者又是Python字典的表示。

请注意,问题中的代码不会产生问题:

>>> import ast
>>> d = {'abc': 1, 'def': 2}
>>> with open("file","w") as f: f.write(str(d))
... 
>>> with open("file","r") as f: ast.literal_eval(f.read())
... 
{'abc': 1, 'def': 2}
>>> type(_)
<type 'dict'>

只有在将字典的字符串表示形式写入文件时使用repr()时,才会生成再次读取文件时看到的输出。例如,即使str(str(d))也不会产生它。