Usando un diccionario como una instrucción de cambio en Python

Estoy tratando de hacer una calculadora simple en Python, usando un diccionario. Aquí está mi código:

def default(): print "Incorrect input!" def add(a, b): print a+b def sub(a, b): print ab def mult(a, b): print a*b def div(a, b): print a/b line = raw_input("Input: ") parts = line.split(" ") part1 = float(parts[0]) op = parts[1]; part3 = float(parts[2]) dict = { '+': add(part1, part3), '-': sub(part1, part3), '*': mult(part1, part3), '/': div(part1, part3) } try: dict[op] except KeyError: default() 

Pero todas las funciones están activadas. ¿Cuál es el problema?

Defina su diccionario como pares de la forma str : function :

 my_dict = {'+' : add, '-' : sub, '*' : mult, '/' : div} 

Y luego, si desea llamar a una operación, use my_dict[op] para obtener una función, y luego pase a llamarla con los parámetros correspondientes:

  my_dict[op] (part1, part3) |___________| | function (parameters) 

Nota: No utilice los nombres incorporados de Python como nombres de variables, o ocultará su implementación. Utilice my_dict lugar de dict por ejemplo.

Se debe a que cuando se llena el diccionario, ejecuta cada operación con los operandos, y al final, está llamando a dict[op] que no contiene None y no hace nada con él.

Lo que ocurre es:

 # NB: in case this is not clear enough, # what follows is the *BAD* code from the OP # with inline explainations why this code is wrong dict = { # executes the function add, outputs the result and assign None to the key '+' '+': add(part1, part3), # executes the function sub, outputs the result and assign None to the key '-' '-': sub(part1, part3), # executes the function mult, outputs the result and assign None to the key '*' '*': mult(part1, part3), # executes the function div, outputs the result and assign None to the key '/' '/': div(part1, part3) } try: # gets the value at the key "op" and do nothing with it dict[op] except KeyError: default() 

Es por eso que obtienes todas las salidas, y no pasa nada en tu bloque try .

Es posible que desee hacer realmente:

 dict = { '+': add, '-': sub, '*': mult, '/': div } try: dict[op](part1, part3) except KeyError: default() 

pero como sugiere sabiamente @christian, no debe usar nombres reservados de python como nombres de variables, ya que esto podría llevarlo a problemas. Y otra mejora que le aconsejo que haga sea imprimir el resultado una vez, y hacer las funciones lambdas:

 d = { '+': lambda x,y: x+y, '-': lambda x,y: xy, '*': lambda x,y: x*y, '/': lambda x,y: x/y } try: print(d[op](part1, part3)) except KeyError: default() 

que devolverá el resultado y lo imprimirá