Usando entrada de usuario para llamar a funciones

Estaba intentando hacer un “juego” en Python donde el usuario ingresa un comando. Sin embargo, no sé si puede tomar esa entrada como un nombre de función. Este es mi esfuerzo actual:

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() 

Aquí, la entrada fue mover, ya que quería probar y llamar a esa función (como podría hacer un usuario final potencial). Sin embargo, me sale el siguiente error:

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

Me preguntaba si habría alguna manera de permitir que un usuario se “moviera” en el juego, lo que el progtwig logra al llamar a la función “mover”.

Parece que estás usando python3.x donde la input devuelve una cadena. Para recuperar el comportamiento de python2.x, necesita eval(input()) . Sin embargo, no debes hacer esto. Es probable que conduzca a un mal día.


Una mejor idea es poner las funciones en un diccionario.

 def move(): #... def jump(): #... function_dict = {'move':move, 'jump':jump } 

y entonces:

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

El siguiente código funciona para mí en python3.2.

 def move(): print("Test.") func_dict = {'move':move} if __name__ == "__main__": input("Press enter to begin.") currentEnvironment = "room" #getNewEnvironment(environments) currentTimeOfDay = "1 AM" #getTime(timeTicks, timeOfDay) print("You are standing in the {0}. It is {1}.".format(currentEnvironment, currentTimeOfDay)) command = input("> ") func_dict[command]() 

Puede acceder a las funciones por nombre usando:

 function = globals()[function_name] 

si la función está en el módulo actual, o

 function = getattr(other_module, function_name) 

También debe tomar medidas para no permitir llamar a funciones arbitrarias, por ejemplo, prefijando:

  def cmd_move() # ok to call this def cmd_jump() # ok to call this def internal_func.... cmd = raw_input('>') # eg "move" fun = globals()['cmd_' + cmd] fun() 

Echa un vistazo al módulo cmd . Ver esto

Por lo general, se usa para los idiomas del estilo shell, pero también se puede usar para crear juegos de aventura de estilo de texto simples.

Puede crear comandos creando un nuevo método en la subclase Cmd .

P.ej

 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" 

Por lo general, es mejor reutilizar el código como sugiere Hans, pero si quisiera ingresar comandos y ejecutarlos manualmente, sería MUCHO más seguro tener un diccionario de comandos válidos que ejecutar directamente la entrada proporcionada por el usuario.

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