2015-04-21 3 views
3

У меня проблема с использованием ast.literal_eval(). В приведенном ниже примере я хочу только преобразовать строку (myText) в dictionnary. Но ast.literal_eval() попытайтесь оценить <__main__.myClass instance at 0x0000000052D64D88> и дайте мне ошибку. Я полностью anderstand этой ошибка, но я хотел бы знать, если есть способ избежать этого (с другой функцией или другим способом, чтобы использовать функцию ast.literal_eval)PYTHON: Есть функция, аналогичная 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 # 

Спасибо заранее за ваши Помогите !

+0

Подумайте об этом вручную, если вы знаете, что 'myText' будет довольно регулярным. 1 Разделите фигурные скобки. 2. Разделите запятую. 3. Разделите каждую результирующую строку на двоеточие и переместите части в словарь. – unwind

+3

Что вы хотите здесь? –

+0

Вы понимаете, что делает 'ast.literal_eval'? Если ваш пример является дословным, то ни ключ, ни значение в вашем представлении словаря не являются фактическим литералом. – user4815162342

ответ

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, необратимо повреждены, и никакое умное разборку не получит потерянные биты.

+0

спасибо! Это похоже на то, что я хочу сделать! – Morgan

Смежные вопросы