#python #python-3.x #dictionary #switch-statement #user-input
#python #python-3.x #словарь #switch-statement #пользовательский ввод
Вопрос:
Я новичок в python и пытаюсь настроить программу командной строки, которая запускает несколько разных команд на основе пользовательского ввода. Пользовательский ввод будет отправлен в функцию со словарем различных функций. Мой код пока выглядит так: `
Функции для различных параметров команды
def quit():
print("youre quiting")
ender = False
def ls():
print("You're listing files!")
Словарь, отображающий ввод в командные функции
def commands(argument):
switcher = {
"quit": quit(),
"ls": ls(),
3: "you typed 3",
}
return switcher.get(argument, "Invalid command")
Основной командный цикл: принимает пользовательский ввод, проверяет, сколько аргументов введено, и вызывает соответствующую командную функцию
while ender == True:
userIn = input("okay go:")
userSplit = userIn.split()
numArgs = len(userSplit)
if numArgs == 0:
print("You must enter a command! Use the command 'help' for more information.")
elif numArgs >= 2:
print("You entered too many arguments! Use the command 'help for more information.")
else:
print(commands(userSplit[0])
Независимо от того, что я ввожу, он вызывает функции ls и quit и печатает их операторы. Однако, если я ввожу недопустимую команду, которая работает и сообщает мне, что она недействительна (в дополнение к вызову этих двух функций).
Что здесь происходит? Как я могу заставить его вызывать только ту функцию, которую я ввожу? Спасибо за ваше время.
Комментарии:
1. Чтобы заполнить ваш
switcher
словарь, интерпретатор должен выполнить эти функции.2. Они вызываются, потому что вы их вызываете. Просто не делайте этого.
3. Итак, как я мог бы вызывать их только после пользовательского ввода? Мне просто нужно использовать большой блок if else?
Ответ №1:
quit()
, например. затем вызывает функцию и сохраняет результирующее значение в качестве значения словаря. Просто сохраните функцию, не вызывая ее сначала:
switcher = {
"quit": quit,
"ls": ls,
"3": lambda: print("You typed 3!")
}
fn = switcher[cmd]
fn() # now call the selected function
Сделайте все значения функциями / лямбдами для единообразия вызова и используйте строки для всех ключей, чтобы они были найдены.
Комментарии:
1. Спасибо! Я действительно не понимал использование лямбды до этого, python начинает иметь для меня больше смысла.
2. Это решает проблему ваших функций — но ваша реализация «quit» не будет работать как есть, потому что переменная «ender» внутри вашего метода quit является локальной для функции — не изменит значение переменной «ender» в вашем исполнении.
Ответ №2:
Когда вы создаете словарь, который вы вызываете ls()
вместо назначения ключа «ls» для ссылки def ls()
на .
Поэтому при каждом вызове commands()
создается словарь и вызываются оба quit()
и ls()
. Ваш словарь во время выполнения становится
{
"ls": None,
"quit": None,
}
def test(argument):
def ls():
print("you're listing")
def lsCorrect():
print("you're listing from a function reference")
switcher = {
"ls": ls(),
"lsCorrect": lsCorrect,
}
return switcher.get(argument, "default")
print('first call')
# switcher[lsCorrect] => reference to lsCorrect, so we then invoke it with ()
test("lsCorrect")()
try:
print('second call')
# when constructing the dictionary ls() is invoked and that function returns None
# so we get a TypeError trying to call a function on None
test("ls")()
except TypeError:
print('tried to invoke something thats not a function')