2015-10-01 2 views
2

Привет коллеги У меня есть код (max_help_position в 2000):max_help_position не работает в питона библиотеке argparse

formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=2000) 
parser = argparse.ArgumentParser(formatter_class=formatter_class) 


subparsers = parser.add_subparsers(title="Commands", metavar="<command>") 

cmd_parser = subparsers.add_parser('long_long_long_long_long_long_long', 
            help='- jksljdalkjda', 
            formatter_class=formatter_class) 

args = parser.parse_args(['-h']) 
print args 

мы имеем

optional arguments: 
    -h, --help       show this help message and exit 

Commands: 
    <command> 
    long_long_long_long_long_long_long 
             - jksljdalkjda 
    small        - descr 

вместо

optional arguments: 
    -h, --help show this help message and exit 

Commands: 
    <command> 
    long_long_long_long_long_long_long - jksljdalkjda 
    small        - descr 

Знаете ли вы, просто как это исправить?

Код:

class MyFormatter(argparse.HelpFormatter): 
    def __init__(self, prog): 
     super(MyFormatter, self).__init__(prog, max_help_position=2000) 
     self._max_help_position = 2000 
     self._action_max_length += 4 

formatter_class = MyFormatter 
parser = argparse.ArgumentParser(formatter_class=formatter_class) 

получил тот же результат.

Код (с шириной = 2000)

formatter_class = lambda prog: argparse.HelpFormatter(prog, 
        max_help_position=2000, width=2000) 

получили тот же результат.

спасибо.

P.S. Также возникает небольшая проблема: это нечетные пробелы в «необязательных аргументах». Вы знаете, как разделять «Команды» и «Необязательные аргументы» для не имеют пробелов в «необязательных аргументах» и имеют пробелы в «Командах», поскольку это разные сущности?

ответ

4

Вам нужно увеличить ширину, а

попробовать:

formatter_class=lambda prog: argparse.HelpFormatter(prog, 
    max_help_position=100, width=200) 

Как мой ранее мысли (ниже) показывают, форматирование учитывает общую ширину, а также значение max_position.


(ранее)

В моем ограниченном тестировании, ваш форматировщик подкласс, кажется, работает. Но я не подтолкнул пределы.

Вам нужно больше копать в код Formatter.

Например есть format_action метод, который фактически использует max_width

def _format_action(self, action): 
    # determine the required width and the entry label 
    help_position = min(self._action_max_length + 2, 
         self._max_help_position) 
    help_width = self._width - help_position 
    action_width = help_position - self._current_indent - 2 
    ... 

Обратите внимание, что он взаимодействует с шириной. Затем он продолжает форматировать строки справки и выполнять обертывание. Таким образом, фактическая реализация не проста.

Я не следую вашему вопросу о пробелах. format_help команды форматирования для форматирования нескольких разделов (включая группы аргументов). Секции (обычно) заканчиваются несколькими линиями. После их сборки форматировщик удаляет «ненужные» линии, оставляя одно пространство между группами. Подпараметр не подходит для других категорий, поэтому мне нужно будет изучить код, чтобы точно увидеть, как он обрабатывается.


Ваше определение lambda также работает. Я этого раньше не видел, и я не думаю, что это то, что планировали разработчики, но Python не имеет значения - если он работает.

Играя со значениями и строками, я вижу, что max_position составляет около 56 работ. Тогда это своего рода палки. Но если я также изменил width (по умолчанию от CONSOLE), я могу увеличить max_position дальше.


Я тестировал это с длинным аргументом parser. Добавление

parser.add_argument('-l','--long','--longlonglonglong', help='help after long option strings') 

производит:

usage: issue25297.py [-h] [-l LONG] <command> ... 

optional arguments: 
    -h, --help          show this help message and 
               exit 
    -l LONG, --long LONG, --longlonglonglong LONG help after long option 
               strings 

Commands: 
    <command> 
    long_long_long_long_long_long_long   - jksljdalkjda 

max_help_position Так делает работу в обычном форматировании синтаксического анализатора. Но по какой-то причине, когда имена подпапок длинны, это не так. Этот раздел требует специального форматирования. Это отступы, а имена подпараметров - не реальные действия (аргументы), а выбор аргумента subparsers. Я изучу его более подробно.

Строка имени субпараметра имеет отступы на 2 дополнительных символа (по сравнению с другими аргументами). Код, который собирает self._action_max_length, не учитывает это. Следовательно, если имя подпарамера является самой длинной строкой, эта max_length закончится на 2 пробела. Сравните фактический v желательно:

long_long_long_long_long_long_long 
            - jksljdalkjda 
long_long_long_long_long_long_long - jksljdalkjda 

(Форматирование выполняется в 2 этапа, когда для вычисления значения, как этот _action_max_length, и второй раз для получения фактической мощности).

Подчиненные отформатированы с рекурсивным вызовом _format_action, поэтому я не оптимистично отношусь к легкому исправлению.


Исправленная форматировщик

Вот исправленная Formatter, что правильно объясняет отступов в subactions (суб парсеров). Когда в Formatter добавляется аргумент (действие), эта функция показывает, насколько широки его строки вызова, и настраивает self._max_action_length. Это используется последним для отступов строк справки.

class MyFormatter(argparse.HelpFormatter): 
    """ 
    Corrected _max_action_length for the indenting of subactions 
    """ 
    def add_argument(self, action): 
     if action.help is not argparse.SUPPRESS: 

      # find all invocations 
      get_invocation = self._format_action_invocation 
      invocations = [get_invocation(action)] 
      current_indent = self._current_indent 
      for subaction in self._iter_indented_subactions(action): 
       # compensate for the indent that will be added 
       indent_chg = self._current_indent - current_indent 
       added_indent = 'x'*indent_chg 
       invocations.append(added_indent+get_invocation(subaction)) 
      # print('inv', invocations) 

      # update the maximum item length 
      invocation_length = max([len(s) for s in invocations]) 
      action_length = invocation_length + self._current_indent 
      self._action_max_length = max(self._action_max_length, 
              action_length) 

      # add the item to the list 
      self._add_item(self._format_action, [action]) 

Пример его использования (не вдаваясь в режиме реального широкий):

# call class with alternate parameters 
formatter_class=lambda prog: MyFormatter(prog, max_help_position=40,width=100) 

parser = argparse.ArgumentParser(formatter_class=formatter_class) 

parser.add_argument('-l','--long', help='help after long option strings') 

subparsers = parser.add_subparsers(title="Commands", metavar="<command>") 

cmd_parser = subparsers.add_parser('long_long_cmd', 
            help='longish command', 
            formatter_class=formatter_class, 
            aliases=['long', 'long_cmd']) 
            # newer arpgarse take aliases 
sht_parser = subparsers.add_parser('short', help = 'short cmd') 

args = parser.parse_args(['-h']) 

, который отображает:

usage: issue25297.py [-h] [-l LONG] <command> ... 

optional arguments: 
    -h, --help      show this help message and exit 
    -l LONG, --long LONG    help after long option strings 

Commands: 
    <command> 
    long_long_cmd (long, long_cmd) longish command 
    short       short cmd 
+0

Как я сказал max_help_position = 100, ширина = 200 и любые другие комбинации и значения не работают (max_help_position = 100, width = 200 или max_help_position = 50, width = 100 или max_help_position = 1000, width = 20000 и т. д.). Спасибо. Я сообщил об этом об этом: http://bugs.python.org/issue25297 –

+0

Он работает, когда регулярный аргумент длинный. Но в вашем случае это имя (-ы) подпункта, которое длинное. – hpaulj

+0

Проблема связана с дополнительным отступом линий подпараметров. Форматтер не учитывает это при расчете '_action_max_length'. В ваших тестовых случаях отступ справки отключен на 2 символа и поэтому переходит к следующей строке. – hpaulj

Смежные вопросы