У вас есть два типа команд: те, которые продвигают итератор, и те, которые не продвигаются.Вы также можете назвать это действием против описательных команд.Концептуально лучше всего иметь цикл while
, который будет продолжать искать ввод, пока вы не получите команду действия.Этот цикл while
будет существовать внутри существующего цикла for
.
Преимущество этого состоит в том, что в настоящее время ваши описательные команды, такие как "help" и "loc", не могут повторяться, но вы, вероятно, хотитеони должны быть.
Другое решение, которое я бы порекомендовал, состоит в использовании отдельных функций для реализации каждой команды.Предоставляя командам согласованный интерфейс, вы облегчаете поддержку и понимание кода.Регистрируя команды в словаре, вы можете сделать поиск более быстрым и гибким.
Следующая концепция имеет набор функций, которые возвращают логическое значение из трех состояний и обновление.Логическое значение True, если команда хочет остаться на текущей строке, False для продолжения.Нет, чтобы выйти.Обновление строки обычно является только вводом.
# in __init__
...
self.command_map = {
'help': self.help,
'loc': , self.loc,
'exit': self.exit,
'inline': self.inline,
}
self.temp = []
...
def help(self, file_as_list, location, line):
self.show_command_list()
return True, line
def loc(self, file_as_list, location, line):
self.show_location(file_as_list, location)
return True, line
def exit(self, file_as_list, location, line):
save_changes = ''
while len(save_changes) != 1 or save_changes.upper() not in 'YN':
save_changes = input('Would you like to save the changes you have made? (Y/N) ')
if save_changes.upper() == 'N':
self.temp = file_as_list
print('Changes were not saved.')
else:
self.temp.extend(file_as_list[location:])
print('Changes were saved.')
return None, line
def inline(self, file_as_list, location, line):
line += ' //' + input(line + ' //')
print('Line generated: ' + line)
return True, line
def process(self):
for location, line in enumerate(file_as_list):
stay = True
while stay:
response = input(line)
command = command_map.get(response.casefold())
if command is None:
print(f'Command "{response}" not found. Try again')
else:
stay, line = command(file_as_list, location, line)
if stay is None:
break
self.temp.append(line)
Учитывая command_map
, вы можете сделать много вещей проще: например, вы можете переопределить show_command_list
, чтобы что-то сделать с sorted(command_map.keys())
.Я уверен, что вы можете видеть, как легко добавить команды в свой список.Вам не нужно повторять шаблонный код, просто будьте осторожны с входными данными и возвращаемыми значениями.
Эту конструкцию также намного проще выполнить вручную, если вам не нравится идея иметь вложенные циклы:
def process(self):
stay = False
iterator = enumerate(file_as_list)
while True:
if not stay:
try:
location, line = next(iterator)
except StopIteration:
break
response = input(line)
command = command_map.get(response.casefold())
if command is None:
print(f'Command "{response}" not found. Try again')
stay = True
else:
stay, line = command(file_as_list, location, line)
if stay is None:
break
if not stay:
self.temp.append(line)
Как видите, этот метод требует немного более специальной обработки для различных условий.