PYTHON:有一个类似于ast.literal_eval()的函数?

时间:2015-04-21 13:55:18

标签: python

我在使用ast.literal_eval()方面遇到了问题。在下面的示例中,我只想将字符串(myText)转换为dictionnary。但ast.literal_eval()尝试评估<__main__.myClass instance at 0x0000000052D64D88>并给我一个错误。我完全理解这个错误,但我想知道是否有办法避免它(使用其他函数或使用其他方法来使用函数ast.literal_eval)

import ast

myText = "{<__main__.myClass instance at 0x0000000052D64D88>: value}"
ast.literal_eval(myText)

# Error: invalid syntax
# Traceback (most recent call last):
#   File "<maya console>", line 4, in <module>
#   File "C:\Program Files\Autodesk\Maya2016\bin\python27.zip\ast.py", line 49, in literal_eval
#     node_or_string = parse(node_or_string, mode='eval')
#   File "C:\Program Files\Autodesk\Maya2016\bin\python27.zip\ast.py", line 37, in parse
#     return compile(source, filename, mode, PyCF_ONLY_AST)
#   File "<unknown>", line 1
#     {<__main__.myClass instance at 0x0000000052D64D88>: value}
#      ^
# SyntaxError: invalid syntax # 

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

您真正想要做的是使用pickle.dump转储数据并使用pickle.load(或等效的,如json等)加载数据。使用repr(data)转储数据会导致这样的问题。

如果您只需要挽救已生成的数据,可能会躲过以下内容:

def my_literal_eval(s):
    s = re.sub(r"<__main__.myClass instance at 0x([^>]+)>", r'"<\1>"', s)
    dct = ast.literal_eval(s)
    return {myClass(): v for v in dct.itervalues()}

使用示例:

>>> import ast, re
>>> class myClass(object): pass
... 
>>> myText = "{<__main__.myClass instance at 0x0000000052D64D88>: {'name': 'theName'}, <__main__.myClass instance at 0x0000000052D73F48>: {'name': 'theName'}}"
>>> my_literal_eval(myText)
{<__main__.myClass object at 0x7fbdc00a4b90>: {'name': 'theName'}, <__main__.myClass object at 0x7fbdc0035550>: {'name': 'theName'}}

仅当myClass个实例没有任何有用信息,但只有身份才需要时,此功能才有效。我们的想法是首先通过将<__main__.myClass instance ...>字符串替换为ast.literal_eval可以解析的内容来修复字符串,然后将其替换为实际的myClass实例 - 前提是这些实例可以在没有论证,这取决于上述假设。

如果这个初始假设不成立,那么你的数据就像Ignacio put it一样,不可逆转地被破坏,并且没有多少聪明的解析会检索丢失的位。