I'm attempting to instantiate an object from a string. Specifically, I'm trying to change this:
from node.mapper import Mapper
mapper = Mapper(file)
mapper.map(src, dst)
into something like this:
with open('C:.../node/mapper.py', 'r') as f:
mapping_script = f.read()
eval(mapping_script)
mapper = Mapper(file)
mapper.map(src, dst)
The motivation for this seemingly bizarre task is to be able to store different versions of mapping scripts in a database and then retrieve/use them as needed (with emphasis on the polymorphism of the map()
method).
The above does not work. For some reason, eval()
throws SyntaxError: invalid syntax.
I don't understand this since it's the same file that's being imported in the first case. Is there some reason why eval()
cannot be used to define classes?
I should note that I am aware of the security concerns around eval()
. I would love to hear of alternative approaches if there are any. The only other thing I can think of is to fetch the script, physically save it into the node package directory, and then import it, but that seems even crazier.
You need to use exec:
eval()
works only for expressions.exec()
works for statements. A typical Python script contains statements.For example:
Output:
Make sure you either call
exec()
(Python 3, in Python 2 it is a statement) at the module level. When you call it in a function, you need to addglobals()
, for exampleexec(code, globals())
, to make the objects available in the global scope and to the rest of the function as discussed here.