0

I am trying to read a line from a file, that already looks like an array, and convert it to an array using this:

eval('points='+lineFromFile)
print(points)

It works, when I try this:

points=[(1, 0, 0, 0), (4752/8677, 7260/8677, 0, -35/8677)]
print(points)

but this does not:

eval('points=[(1, 0, 0, 0), (4752/8677, 7260/8677, 0, -35/8677)]')
print(points)

Why is that and how can I fix it?

  • 2
    I think you're mixing up `exec` and `eval`. You would need to either do `exec('points=[(1, 0, 0, 0), (4752/8677, 7260/8677, 0, -35/8677)]')` or (much better) `points = eval('[(1, 0, 0, 0), (4752/8677, 7260/8677, 0, -35/8677)]')` – Morgan Thrapp Jun 15 '16 at 15:34
  • Adding to what @MorganThrapp suggests, I recommend reading [What's the difference between eval, exec, and compile in Python?](http://stackoverflow.com/questions/2220699/whats-the-difference-between-eval-exec-and-compile-in-python). ... and: Welcome to StackOverflow. – Dilettant Jun 15 '16 at 15:39
  • If the contents of a file look like valid Python, `import` is the preferred way of loading and parsing it. – hpaulj Jun 15 '16 at 16:43

1 Answers1

2

I'm going to answer the "how can I fix it" part of the question and suggest that you use ast.literal_eval:

import ast
points = ast.literal_eval(lineFromFile)

This has the side benefit that it should be safe from malicious code execution and is generally cleaner and easier to read. The downside is that as the name implies, this will only evaluate python literals (no variables).

Another option is to use json.loads -- Depending on the input string, this may work and will probably be faster. From what I can tell of your example, json won't work, but I mention it here just in case.


If you must use eval/exec (I hope you trust the creator of the file!), then you're best bet is probably to do something like:

points = eval(lineFromFile)

rather than trying to add the variable name to the string and then exec it. You can do some things to try to make eval a little safer, but at the end of the day, you're probably only giving yourself a false sense of security if you do that...

mgilson
  • 300,191
  • 65
  • 633
  • 696