How to eval a file
Alexander Schmolck
a.schmolck at gmx.net
Sat Feb 22 12:36:35 EST 2003
d95-bli at nada.kth.se (Björn Lindberg) writes:
> I'm writing a program with a "configuration file" if you will, that
> looks something like this:
>
> --------------------------------
> collection = '''Abba %sdabba'''
> topic = '''Gucko %s'''
> --------------------------------
>
> I have trouble getting this information into Python. I was hoping I
> could read this file as a string and then eval() it, to get the
> variables collection & topic set to the respective strings in the
> local context. Ie, in a class method:
>
> def read_file(name):
You mean ``def read_file(self, name):`` I take it?
> f = open(name, 'r')
> string = f.read()
> eval(string)
>
> self.collection = collection
> self.topic = topic
> ...
>
> f.close()
The code is not only broken, it's also a bad way to set about it, e.g. why
would you want to mess up your functions namespace? Think of what would happen
if the configuration file contained a name you use (e.g. "f", "self" etc.).
Also, if you don't have control over the file's contents, someone might just
enter code that formats your harddisk.
>
> This gives the following error message:
>
> File "<string>", line 3
> collection = '''<h3%s</h3>'''
> ^
> SyntaxError: invalid syntax
This is because eval only works for expressions (i.e. something that returns a
value), assignment ('=') is a statement (as are 'if', 'for' etc.). So
f = eval('3 + 4')
will work fine.
eval('f = 3 + 4')
won't. If you want to execute arbitrary code (and not just expressions), use
exec or execfile.
>
> So I tried using execfile(name) instead, but that doesn't work
> either.
It does, you're just not using it correctly (and don't give many hints as to
what exactly you did). Try this [UNTESTED]:
namespace = {}
execfile(filename, namespace)
self.collection = namespace['collection']
>
> The only thing I can come up with now is to import the file. This has
> a number of drawbacks however: (i) I would have to modify the module
> search path, (ii) The file would have to be named .py, (iii) It looks
> ugly (at least to me) to have an import statement inside a function,
> (iv) I am not even sure it would work as I expect.
>
> Is there another way?
Yes. Doing it properly (without any exec*s). If your configuration file just
looks like
var1 = '''some string'''
var2 = '''some other string'''
then parse it, it isn't particularly difficult.
alex
More information about the Python-list
mailing list