Josef Meile wrote:
I've seen this question here several times. Even I made it once long time ago. I could solve it easily because I didn't have a complex list.
Here's another way (in Python 2.3): from compiler import parse, ast class LiteralExEval(object): """ Evaluate a string as a single expression consisting of literals. """ def __call__(self, s): tree = parse(s) if tree.doc is not None: if tree.node.nodes: raise ValueError, 'Too many expressions.' return tree.doc nodes = tree.node.nodes if len(nodes) < 1: raise ValueError, 'Empty expression.' if len(nodes) > 1: raise ValueError, 'Too many expressions.' node = nodes[0] if node.__class__ <> ast.Discard: raise ValueError, 'String is not an expression.' return self.dispatch(node.getChildNodes()[0]) def dispatch(self, node): kind = node.__class__.__name__ f = getattr(self, 'eval' + kind, None) if f is None: raise ValueError, '%s not allowed in expression.' % kind return f(node) def evalConst(self, node): return node.value def evalList(self, node): e = self.dispatch return [e(n) for n in node.nodes] def evalTuple(self, node): return tuple(self.evalList(node)) def evalDict(self, node): e = self.dispatch return dict([(e(k), e(v)) for k, v in node.items]) class NameExEval(LiteralExEval): """ Evaluate a string as a single expression that contains literals and pre-defined names. """ def __init__(self, names={'None': None, 'True': True, 'False': False}, **kwnames): kwnames.update(names) self._names = kwnames def evalName(self, node): try: return self._names[node.name] except KeyError: raise ValueError, 'Undefined name %s' % `node.name` class NameCallExEval(NameExEval): """ Evaluate a string as a single expression that contains literals and pre-defined names, including callable names. """ def evalCallFunc(self, node): if node.star_args or node.dstar_args: raise ValueError, 'Function uses * or **-style arguments.' e = self.dispatch f = e(node.node) args = [] kwargs = {} for arg in node.args: if arg.__class__ == ast.Keyword: kwargs[arg.name] = e(arg.expr) else: args.append(e(arg)) return f(*args, **kwargs) def _debug(Eval, s): try: return Eval(s) except ValueError, e: print '%s: %s' % (`s`, str(e)) if __name__ == '__main__': le = LiteralExEval() for s in ( "'string'", "42", "1, 0x2", "['one', 0.2]", "{1j: ()}", ): print _debug(le, s) ne = NameExEval(x=42) for s in ( "None", "[x, 2, True]", "{False: (2, ['x']),}", ): print _debug(ne, s) nc = NameCallExEval(x='42', Int=int, Str=str) for s in ( "Str(4)", "Int(x)", "Str(Int(x,),)", ): print _debug(nc, s)