eval vs. exec

Michael Hudson mwh at python.net
Mon May 27 12:53:09 EDT 2002


Simon Budig <Simon.Budig at unix-ag.org> writes:

> Alexander Schmolck <a.schmolck at gmx.net> wrote:
> > Simon Budig <Simon.Budig at unix-ag.org> writes:
> > 
> > The distiction is quite simple: use eval for expressions and exec for
> > everything else. That of course only works if you know what qualifies as an
> > expression in python :)
> 
> I think I do know what an expression is - what I do not know is
> how to determine the type to use from a string given by an external
> source.

Hmm.  Maybe compile as "single" but smash the last PRINT_EXPR into a
RETURN_VALUE?  Might work.  You'd probably want to turn all but the
last PRINT_EXPR into POP_TOPs too...

Something like this?

import new, dis

POP_TOP = dis.opname.index("POP_TOP")
PRINT_EXPR = dis.opname.index("PRINT_EXPR")
RETURN_VALUE = dis.opname.index("RETURN_VALUE")

def super_eval(expr):
    code = compile(expr, "", "single")

    codestring = code.co_code
    newcode = ""

    last_i = 0
    i = 0
    while i < len(codestring):
        op = ord(codestring[i])
        if op > dis.HAVE_ARGUMENT:
            newcode += codestring[i:i+3]
            i += 3
        elif op == PRINT_EXPR:
            last_i = i
            newcode += chr(POP_TOP)
            i += 1
        else:
            newcode += chr(op)
            i += 1

    if last_i > 0:
        newcode = newcode[:last_i] + chr(RETURN_VALUE) + newcode[last_i+1:]

    code = new.code(code.co_argcount, code.co_nlocals, code.co_stacksize,
                    code.co_flags, newcode, code.co_consts, code.co_names,
                    code.co_varnames, code.co_filename, code.co_name,
                    code.co_firstlineno, code.co_lnotab)

    return eval(code)

>>> super_eval("a = 2")
>>> super_eval("3*4")
12
>>> super_eval("a = 2; b = 3; a*b")
6


buyer-beware-ly y'rs
M.

-- 
  I think my standards have lowered enough that now I think ``good
  design'' is when the page doesn't irritate the living fuck out of 
  me.                        -- http://www.jwz.org/gruntle/design.html



More information about the Python-list mailing list