Когато се използва argparse, той осигурява автоматична обработка за -h
/--help
команди. Дори и да са добавени подразбори, той обработва тяхната „помощ за подразбори“, както и глобална помощ, която предоставя списък на тези подразбори.
Дотук добре.
Добавяне на помощна команда
Учтивост към потребителя е да добавите help
command, ако се използват подпарсери. Най-добрата практика е да дадете на потребителя и двата начина да види помощ: program subcommand --help
и program help subcommand
.
За съжаление, argparse не предоставя такъв лукс. Човек трябва да го направи сам.
Дисекция на проблем
- Добавете команда
help
. Тривиално, просто добавете още един подпарсер. - Намерете даден поданализатор от друг поданализатор и намерете всички поданализатори
- Намерете как да отпечатате помощ за даден подпарсер
Налични данни и обхват: Извикваме command
на поданализатора (най-добрата практика е да използваме subparser.set_defaults(command=myfunc)
; имаме достъп само до поданализатора, но не и до самия ArgumentParser()
. Такова нещо се случва често, когато разделяте команди на автономни класове със следния код:
subparsers = self.parser.add_subparsers(title=’commands’) FirstCommand(subparsers) SecondCommand(subparsers)
и всяка команда добавя собствени опции като тази:
class GenericCommand(object): def __init__(self, subparsers): self.parser = subparsers.add_parser(self.name, help=self.help) self.parser.add_argument(...) ...subparsers.set_defaults(command=self.command)
def command(self, args): ....
Търсене на подпарсери
Доста разочароващо е, но и dict(subparsers)
, и list(subparsers)
не работят. Документацията не изяснява вътрешността на argparse, така че използвах интроспекция, за да погледна вътре.
Открих, че subparsers
има атрибут .choices
, който съдържа всички налични подпарсери като OrderedDict
. Може да бъде достъпен чрез ключ, може да се повтори над ключове или стойности. Всичко, от което се нуждаем.
Помощно съобщение
Всеки подпарсер или съдържание на choices
има функция print_help()
, която прави всичко, както очаквате.
Полученият код
class HelpCommand(object): def __init__(self, subparsers): self.parser = subparsers.add_parser( 'help', help='display help' ) self.parser.add_argument( 'name', nargs='?', help='Command to show help for' ) self.subparsers = subparser self.parser.set_defaults(command=self.command) def command(self, args): if args.name: self.subparsers.choices[args.name].print_help() else: print("Use help [name] to show help for given command") print("List of available commands:") print("\n".join(list(self.subparsers.choices.iterkeys()))) parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title='commands') FirstCommand(subparsers) SecondCommand(subparsers) HelpCommand(subparsers) args = parser.parse_args() args.command()