2

I've got a problem with the utilisation of ast.literal_eval(). In the example below, I only want to convert the string (myText) to dictionnary. But ast.literal_eval() try to evaluate <__main__.myClass instance at 0x0000000052D64D88> and give me an error. I completely anderstand this error but I would like to know if there is a way to avoid it (with an other function or with an other way to use the function 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 # 

Thank you in advance for your help !

10
  • Consider doing it manually, if you know that the myText is going to be fairly regular. 1 Strip the braces. 2. Split on comma. 3. Split each resulting string on the colon, and shove the parts into a dictionary. Commented Apr 21, 2015 at 13:58
  • 3
    What do you want to happen here? Commented Apr 21, 2015 at 13:58
  • Do you understand what ast.literal_eval does? If your example is verbatim, then neither the key nor the value in your dictionary representation is an actual literal. Commented Apr 21, 2015 at 14:01
  • 4
    If you are storing this kind of information as a string, you are probably trying to solve a problem the wrong way. What fundamental problem are you trying to solve/for what do you want to evaluate this string? Commented Apr 21, 2015 at 14:04
  • 1
    Your data is already irreversibly damaged. Using a smarter parser won't help. Commented Apr 21, 2015 at 14:09

1 Answer 1

3

What you really want to do is dump your data using pickle.dump and load it using pickle.load (or equivalent, such as json, etc.). Using repr(data) to dump the data will cause problems like this.

If you just need to salvage the data you have already generated, you might get away with something like the following:

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()} 

Example of usage:

>>> 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'}} 

This will work only if the myClass instances don't have any useful information, but are only needed for identity. The idea is to first fix up the string by replacing the <__main__.myClass instance ...> strings with something that can be parsed by ast.literal_eval, and then replace those with actual myClass instances - provided these can be constructed without arguments, which hinges on the above assumption.

If this initial assumption doesn't hold, then your data is, as Ignacio put it, irreversibly damaged, and no amount of clever parsing will retrieve the lost bits.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks ! It look like perfect for what I want to do !

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.