You really, really, really don't want to try to use repr
and eval
as a serialization format.
If you just used, say, pickle
, you wouldn't have this problem at all:
with open("task_list2.dat", "wb") as outFile:
pickle.dump(task_list, outFile)
with open("task_list2.dat", "rb") as file:
task_list = pickle.load(file)
Much simpler, yes?
But if you want to know how to solve the immediate problem instead of making it irrelevant: You've got multiple problems in your __repr__
method, all of which need to be fixed if you want it to be round-trippable.
- You generate a string representation… and then call
repr
on it. You want to return the string representation, not a string representation of the string representation. Just leave out therepr
. - You should always delegate to the
repr
of sub-objects, not thestr
. If you're using%
-formatting, that means using%r
rather than%s
. - Don't try to add quotes around things. That may happen to work if the object itself has no quotes, backslashes, invisible characters, etc. in it, but why rely on that? If you think you need quotes, it's pretty much always a sign that you broke the previous rule, and you should fix that instead.
Here's how you can write a round-trippable repr for this class:
def __repr__(self):
return 'Task(%r, %r)' % (self.name, self.timespent))
And you can verify that it does what you want:
>>> t = Task('task name', 23.4)
>>> t
Task('task name', 23.4)
>>> eval(repr(t))
Task('task name', 23.4)
Of course in your particular example, just fixing the first problem (removing the spurious call to repr
) would have gotten rid of the single quotes and made that particular example work. You could also hack around that on the read side by calling eval
twice. Or, for this particular example, even by calling eval(s[1:-1])
or eval(s.strip("'"))
. But any "fix" like that is just going to make it harder to debug the general problems you're going to run into once you have, e.g., a name that isn't as simple as a single all-ASCII-letter word.