0

Im writing a python script and what I would like to do is capture the input into a variable and then use that to call a function with that name. Here is an example:

def test():
    print "You want to do a test!"

option = raw_input("What do you want to do? ") #User types in test
option()

Now this isnt working since python is not seeing option as a variable but rather is trying to call the function "option". What is the bast way to go about doing this?

stevo81989
  • 170
  • 1
  • 9

5 Answers5

3

eval() will work, but as @MattDMo said it can be dangerous.

A much safer way to do this, if your functions are module globals:

globals()[option]()

globals() is a dictionary mapping strings to the module global objects those strings are bound to. So globals()[option] looks up the string bound to option in that dict, and returns the object; e.g., globals["test"] returns the function object for test(). Then adding () at the end calls that function object. Bingo - you're done.

Tim Peters
  • 67,464
  • 13
  • 126
  • 132
  • very good, I'd forgotten about that... – MattDMo Dec 13 '13 at 04:04
  • Awesome! I think thats a winner! Now all I need is to figure out functions that take multiple inputs and a catch all but I think I can do that with a try/except. Thanks for the help! – stevo81989 Dec 13 '13 at 04:13
0

You want to be very careful about running arbitrary code, but if you absolutely need to, you can use the eval() function.

What might be a better way is to give your user a menu of options, then do testing on the contents of option to see which one they picked, then run that function.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • Hm, interesting. So what we are trying to do is to basically have an interactive shell and based on what the user inputs a function will run based on the input. So if the user types ls it will run a function that lists files from an api. Right now we have if input == "ls": do funtion I would like to have it so I can just add a new function without having a massive amount of if statements. I was just wondering if anyone had a simpler idea. – stevo81989 Dec 13 '13 at 04:01
  • you don't need a huge amount of if statements, you can always store the function names in a list, then do `if option in list: ... ` – MattDMo Dec 13 '13 at 04:03
  • I like that, thats a good idea. I like Tim Peters too though. I think it will work well, the only thing left is to figure out a catch all (if the command isnt found as a function) and ones with multiple optins (?,h,help all point to a function) but that may be easily done with a try/except. Thanks for the help! – stevo81989 Dec 13 '13 at 04:08
0

You can use python eval.

From the help page, eval evaluates the source in the context of globals and locals. The source may be a string representing a Python expression or a code object as returned by compile().

For example:

 def a():
     print "Hello"

 inp = raw_input()
 eval(inp + "()")

On entering a at the stdin, the function a will be executed. Note that this could be dangerous without any safety checks.

Harry
  • 394
  • 2
  • 10
0

This is, I suppose, an actual use for bare input:

option = input("What do you want to do? ") #User types in test
option()

This is semantically equivalent to eval(raw_input()). Note that in python 3, raw_input becomes input so you will explicitly have to eval it.

The usual caveats of this type of operation being incredibly unsafe apply. But I think that's obvious from your requirement of giving the user access to run arbitrary code, so...

roippi
  • 25,533
  • 4
  • 48
  • 73
0

I like using a dict in situations like this. You can even specify a default option if the user provides an answer that isn't expected.

def buy_it():
    print "use it"

def break_it():
    print "fix it"

def default():
    print "technologic " * 4

menu = {"buy it": buy_it, "break it": break_it}
option = raw_input("What do you want to do? ")
menu.get(option, default)()
clu_
  • 46
  • 4