2

I was trying to make a "game" in Python where the user inputs a command. However, I do not know whether you can take that input to be a function name. This is my current effort:

def move():
    print("Test.")

if __name__ == "__main__":
    input("Press enter to begin.")
    currentEnvironment = getNewEnvironment(environments)
    currentTimeOfDay = getTime(timeTicks, timeOfDay)
    print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay))
    command = input("> ")
    command()

Here, the input was move, as I wanted to try and call that function (as a potential end user might). However, I get the following error:

Traceback (most recent call last):
  File "D:\Text Adventure.py", line 64, in <module>
    command()
TypeError: 'str' object is not callable

I was wondering if there was any way that I could allow a user to 'move' in the game, which the program achieves by calling the "move" function.

4
  • If you could make this work, what happens when the user types os.system('rm -rf')? Commented Sep 19, 2012 at 13:01
  • @DanielRoseman -- Nothing because rm needs to be provided with something to remove. However, os.system('rm -rf ~') could be bad ;) Commented Sep 19, 2012 at 13:07
  • Sorry, I'm not hugely familiar with the OS module. Commented Sep 19, 2012 at 13:09
  • Hi Jon, command becomes a string as soon as it gets input, and you cannot make a function call out of it. Hence, Python tells you 'str' object is not callable What you could do is have a generic user_command() function that uses switch-case to get your program to do what you want it to do. Commented Sep 19, 2012 at 17:20

4 Answers 4

7

It looks like you're using python3.x where input returns a string. To recover the python2.x behavior, you need eval(input()). However, you shouldn't do this. It's likely to lead to a bad day.


A better idea is to put the functions into a dictionary --

def move():
    #...

def jump():
    #...

function_dict = {'move':move, 'jump':jump }

and then:

func = input('>')  #raw_input on python2.x
function_dict[func]()

The following code works for me on python3.2.

def move():
    print("Test.")

func_dict = {'move':move}
if __name__ == "__main__":
    input("Press enter to begin.")
    currentEnvironment = "room" #getNewEnvironment(environments)
    currentTimeOfDay = "1 A.M." #getTime(timeTicks, timeOfDay)
    print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay))
    command = input("> ")
    func_dict[command]()
Sign up to request clarification or add additional context in comments.

8 Comments

Where do I put the dictionary, exactly? I'm getting: NameError: name 'move' is not defined
@Jon -- function_dict needs to be created after the functions are created. e.g. def move(): ...; def move_left(): ...; function_dict = {'move':move, ... }
Edit - was a bug with something I accidentally left in there previously, thanks a bunch :)
@Jon -- I posted a working version of the snippet you had above using python 3.2
@mgilson Hi Mate, Still helping 8 years later :-) , Cheers
|
2

You can access functions by name using:

function = globals()[function_name]

if the function is in the current module, or

function = getattr(other_module, function_name)

You should also take measures to disallow calling arbitrary functions, for example, prefixing:

 def cmd_move() # ok to call this
 def cmd_jump() # ok to call this

 def internal_func....

 cmd = raw_input('>') # e.g. "move"
 fun = globals()['cmd_' + cmd]
 fun()

Comments

2

Have a look at the cmd module. See this.

It is normally used for shell style comman dlanguages, but it can also be used to create simple text style adventure games.

You can create commands by creating a new method on the Cmd subclass.

E.g.

def do_move(self, args):
    if self.next_room.has_snake():
        print "The next room contains a poisonous snake. It bites you and you die."
    else:
        print "The room is empty"

3 Comments

I'm looking to use this in school, where cmd is not accessible.
Just to clarify, as I am not sure if I was clear on this. I do not mean cmd as in the windows command prompt. I mean the python cmd module, which should be available in any python installation.
Or do you mean that you are not allowed to use the cmd python module?
0

It's usually better to re-use code as Hans suggests, but if you wanted to input commands and run them manually, it would be MUCH safer to have a dictionary of valid commands than to directly execute user-provided input.

cmd = { 'move': move, 'jump': jump, 'look': look }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.