Использование словаря в качестве оператора switch в Python
Я пытаюсь сделать простой калькулятор в Python, используя словарь. Здесь мой код:
def default():
print "Incorrect input!"
def add(a, b):
print a+b
def sub(a, b):
print a-b
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()
но все функции активированы. В чем проблема?
Ответы
Ответ 1
Определите свой словарь как пары формы str : function
:
my_dict = {'+' : add,
'-' : sub,
'*' : mult,
'/' : div}
И затем, если вы хотите вызвать операцию, используйте my_dict[op]
для получения функции, а затем передайте ее с соответствующими параметрами:
my_dict[op] (part1, part3)
|___________|
|
function (parameters)
Примечание. Не используйте встроенные имена Python в качестве имен переменных, иначе вы скроете его реализацию. Используйте my_dict
вместо dict
, например.
Ответ 2
Это происходит потому, что, когда словарь заполняется, он выполняет каждую операцию с операндами,
и в конце вы вызываете dict[op]
, который содержит None
и ничего не делать с ним.
Что происходит:
# N.B.: 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()
поэтому вы получаете все выходы, и ничего не происходит в вашем блоке try
.
Возможно, вы захотите:
dict = {
'+': add,
'-': sub,
'*': mult,
'/': div
}
try:
dict[op](part1, part3)
except KeyError:
default()
но, как подсказывает @christian, вы не должны использовать зарезервированные имена python в качестве имен переменных, что может привести к неприятностям. И еще одно улучшение я советую вам todo - напечатать результат один раз и выполнить функции lambdas:
d = {
'+': lambda x,y: x+y,
'-': lambda x,y: x-y,
'*': lambda x,y: x*y,
'/': lambda x,y: x/y
}
try:
print(d[op](part1, part3))
except KeyError:
default()
который вернет результат и распечатает его