在验证任务管理器CLI的用户输入时遇到问题



我想让函数做的是提示用户输入有效的命令。有效命令列表由变量valid_cmd定义,它是一个对列表,每对由一个object_type和一个cmd元素组成。

我遇到的问题是,当用户输入任意数量的错误答案时,它会提示用户输入另一个命令,这是应该的,但是当用户最终输入一个有效的命令时,该函数返回所有输入,包括无效的输入。我怀疑我对函数递归是如何工作的以及如何正确地执行它有一个根本性的误解。

def collect():
user_cmd = input("Manager Command > ")
user_cmd = user_cmd.split(" ")
try:
user_cmd = [user_cmd[0], user_cmd[1], " ".join(user_cmd[2:])]
# Checks to make sure command is valid (up to index 1)
object_types = ["task", "folder"]
cmds = [["new", "edit", "del", "done"], ["new", "edit", "del"]]
valid_cmds = []
for item in cmds[0]:
valid_cmds.append([object_types[0], item])
for item in cmds[1]:
valid_cmds.append([object_types[1], item])
if user_cmd[0:2] not in valid_cmds:
print("Invalid input")
collect()
except IndexError:
print("Invalid input.")
collect()
return user_cmd

您的函数在输入无效时再次调用自己-因此您编写了一个递归函数。在这种情况下,这会使事情变得比他们需要的更复杂。您应该在这里分离关注点:collect已经解析了用户输入。当输入无效时,它也不应该决定该做什么。这应该在函数之外完成。

我的建议:当输入无效时,让collect返回None。处理在函数之外的循环中反复要求用户输入有效的输入:

def collect():
user_cmd = input("Manager Command > ")
user_cmd = user_cmd.split(" ")
try:
user_cmd = [user_cmd[0], user_cmd[1], " ".join(user_cmd[2:])]
# Checks to make sure command is valid (up to index 1)
object_types = ["task", "folder"]
cmds = [["new", "edit", "del", "done"], ["new", "edit", "del"]]
valid_cmds = []
for item in cmds[0]:
valid_cmds.append([object_types[0], item])
for item in cmds[1]:
valid_cmds.append([object_types[1], item])
if user_cmd[0:2] not in valid_cmds:
print("Invalid input")
return
except IndexError:
print("Invalid input.")
return None
return user_cmd

if __name__ == '__main__':
while True:
valid_command = collect()
if valid_command:
break
print(f"command: {valid_command}")

事实上,虽然上面的代码工作,我将进一步建议也做parse_command之外的input部分。这也将使函数更容易测试。

def parse_command(cmd):
user_cmd = cmd.split(" ")
try:
user_cmd = [user_cmd[0], user_cmd[1], " ".join(user_cmd[2:])]
# Checks to make sure command is valid (up to index 1)
object_types = ["task", "folder"]
cmds = [["new", "edit", "del", "done"], ["new", "edit", "del"]]
valid_cmds = []
for item in cmds[0]:
valid_cmds.append([object_types[0], item])
for item in cmds[1]:
valid_cmds.append([object_types[1], item])
if user_cmd[0:2] not in valid_cmds:
print("Invalid input")
return
except IndexError:
print("Invalid input.")
return None
return user_cmd

if __name__ == '__main__':
while True:
user_input = input("Manager Command > ")
valid_command = parse_command(user_input)
if valid_command:
break
print(f"command: {valid_command}")

最新更新