Эпилог ArgumentParser и форматирование описания в сочетании с ArgumentDefaultsHelpFormatter

Я использую argparse для ввода командной строки, а также для создания текста справки. Я хочу использовать ArgumentDefaultsHelpFormatter Как formatter_class, однако, это мешает мне также используя RawDescriptionHelpFormatter что позволит мне добавить пользовательское форматирование в мое описание или эпилог.

есть ли разумный метод достижения этого помимо написания кода для создания текста для значений по умолчанию? Согласно документам argparse, все внутренности ArgumentParser рассматриваются реализации детали, а не публичный API, поэтому подкласс не является привлекательным вариантом.

2 ответов


Я просто попробовал подход множественного наследования, и он работает:

class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
    pass

parser = argparse.ArgumentParser(description='test\ntest\ntest.',
                                 epilog='test\ntest\ntest.',
                                 formatter_class=CustomFormatter)

Это может сломаться, если внутренние части этих классов изменятся.


Я не понимаю, почему подклассы a HelpFormatter должна быть проблема. Это не имеет никакого отношения к внутренностям ArgumentParser. В документации есть примеры custom Action и Type классов (или функций). Я беру 'there are four such classes' строка будет приглашением написать мой собственный HelpFormatter, если это необходимо.

предоставленную HelpFormatter подклассы делают довольно простые изменения, изменяя только одну функцию. Поэтому их можно легко скопировать или изменить.

RawDescription просто изменения:

def _fill_text(self, text, width, indent):
    return ''.join(indent + line for line in text.splitlines(keepends=True))

теоретически это может быть изменено без изменения API, но это маловероятно.

форматер по умолчанию просто изменяется:

def _get_help_string(self, action):
    help = action.help
    if '%(default)' not in action.help:
        if action.default is not SUPPRESS:
            defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
            if action.option_strings or action.nargs in defaulting_nargs:
                help += ' (default: %(default)s)'
    return help

вы можете получить тот же эффект, просто включив %(default)s во всех ваших аргументах строки справки. В отличие от Raw подклассы, это просто класс удобство. Это не дает вам больше контроля над форматированием.