an eval()-like exec()

Matt McCredie mccredie at gmail.com
Mon Aug 27 19:06:28 EDT 2007


> A python interactive interpreter works by having the user type in some
> code, compiling and running that code, then printing the results. For
> printing, the results are turned into strings.
>
> I would like make an interpreter which does this, without the last
> part: i.e. where the results are returned as objects, instead of as
> strings. I.e. have I would like to see something that behaves like
> this:
>
> >>> ip = MyInterpreter()
> # this started a new interpreter
> >>> ip.run("import math") is None
> True
> >>> ip.run("math.pi") is math.pi
> True
>
> Neither exec() or eval() is usable for this, as far as I see, because
> eval can't handle arbitrary python code (eval("import math") ), and
> exec() doesn't return the results.
>
> Subclassing an code.InteractiveInterpreter or code.InteractiveConsole
> seems like a usable idea, but I couldn't find out what to do to get
> the results before they are turned into strings.
>
> Using compile() and then eval() didn't seem usable either.
>
> Any ideas?

Well, my first thought is that exec and eval serve two different
purposes, and you should just have both of them and use the
appropriate one based on the situation. However, I think it is
possible to enable the behavior you want:

[code]
def myeval(statement, globals_=None, locals_=None):
    try:
        return eval(statement, globals_, locals_)
    except SyntaxError:
        if locals_ is None:
            import inspect
            locals_ = inspect.currentframe().f_back.f_locals
        exec statement in globals_, locals_
[/code]

It seems to work for me.

Matt



More information about the Python-list mailing list