0

I have a list that I have successfully converted into a python statment

ex:

from operator import mul,add,sub,abs

l = ['add(4,mul(3,abs(-3)))']

I was wondering what would I use to RUN this string as actual python code? I should be expecting a output of 13. I want to input the 0th value of the list into a function that is able to run this value as actual python code.

3
  • 1
    Why do you want to do this? Whatever you're trying to do, there's much likely a better way to do it. Commented Nov 29, 2013 at 0:39
  • @abarnert Im trying to parse an expression and convert it into python to compute a value. However ,after reading more closely I do not think I can use exec() as it is based off of eval() and I cannot use eval(). (part of an assignment). I think I am going to have to write this parser another way Commented Nov 29, 2013 at 0:42
  • The fact that the assignment says you can't use eval implies that "convert it into Python to compute a value" is the wrong approach in the first place. You need to parse an expression and then evaluate that parsed expression, as appropriate for the expression language, not as Python. Commented Nov 29, 2013 at 1:10

4 Answers 4

2

You don't want to run this as Python code. You're trying to parse expressions in some language that isn't Python, even if it may be superficially similar. Even if it's a proper subset of Python, unless, say, __import__('os').system('rm -rf /') happens to be a valid string in the language that you want to handle by erasing the hard drive, using eval or exec is a bad idea.

If the grammar is a proper subset of Python, you can still use the ast module for parsing, and then write your own interpreter for the parsed nodes.

However, I think what you really want to do here is build a very simple parser for your very simple language. This is a great opportunity to learn how to use a parsing library like pyparsing or a parser-generator tool like pybison, or to build a simple recursive-descent parser from scratch. But for something this simple, even basic string operations (splitting on/finding parentheses) should be sufficient.

Here's an intentionally stupid example (which you definitely shouldn't turn in if you want a good grade) to show how easy it is:

import operator

OPERATORS = operator.__dict__

def evaluate_expression(expr):
    try:
        return int(expr)
    except ValueError:
        pass
    op, _, args = expr.rpartition('(')
    rest, _, thisop = op.rpartition(',')
    args = args.rstrip(')').split(',')
    argvalues = map(int, args)
    thisvalue = OPERATORS[thisop](*argvalues)
    if rest:
        return evaluate_expression('{},{}'.format(rest, thisvalue))
    return thisvalue

while True:
    expr = input()
    print(evaluate_expression(expr))

Normally, you want to find the outermost expression, then evaluate it recursively—that's a lot easier than finding the rightmost, substituting it into the string, and evaluating the result recursively. Again, I'm just showing how easy it is to do even if you don't do it the easy way.

Sign up to request clarification or add additional context in comments.

Comments

2

use exec like this:

exec('add(4,mul(3,abs(-3)))')

That should work

more about exec

3 Comments

i tried that in my interpreter and I didn't get any output =/
@Liondancer Because there is no print statement inside the code. Change it to 'print add ....'
yes you would need to do exec('print add(4,mul(3,abs(-3)))')
1

If you want to evaluate a Python expression, use eval. This returns the value of the evaluated expression. So, for example:

>>> eval(l[0])
13
>>> results = [eval(expr) for expr in l]
>>> results
[13]

However, any time you find yourself using eval (or exec or related functionality), you're almost always doing something wrong. This blog post explains some of the reasons why.

1 Comment

Yes I've been hearing about this from my searches. So far I've parsed the expression into a list of ints and strings and I was going to put them together and run the code into exec(). But I am not allowed to use functions that evaluate the expression for me so I need to do it another way. I appreciate your help thank you! All these posts are the correct answers for my question. I need to ask a different question for my situation.
1

since you're evaluating an expression, eval would suit you better than exec. Example:

x = -3
y = eval('add(4,mul(3,abs(x)))')
print y

Note the security implication of exec and eval, since they can execute arbitrary code, including for example deleting all files you have access, installing Trojans to your doc files, etc.

Check out also ast.literal_eval for python 2.6+.

1 Comment

ast.literal_eval only evaluates literals; it won't work on an expression with function calls in it. (That's why it's safe in the first place.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.