Ответ 1
Об этом сообщается сообщение об ошибке: http://bugs.python.org/issue9338
опции argparse с nargs = '?', '*' или '+' не могут сопровождаться позициями
Простым (пользовательским) исправлением является использование --
для разделения столбцов от опций:
./test.py -o 0.21 0.11 0.33 0.13 -- 100
Я написал патч, который резервирует некоторые аргументы для использования позицией. Но это не тривиальный вариант.
Что касается изменения строки использования - проще всего написать свой собственный, например:
usage: test.py [-h] positional [-o OPTIONAL [OPTIONAL ...]]
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] -- positional
Я бы не рекомендовал добавлять логику к формату использования, чтобы сделать такое изменение. Я думаю, что это будет слишком сложно.
Еще одно быстрое решение - превратить этот позиционный элемент в необязательный. Это дает пользователю полную свободу в отношении их порядка и может уменьшить путаницу. Если вы не хотите путать "обязательный необязательный", просто дайте ему логическое значение по умолчанию.
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] -p POSITIONAL
usage: test.py [-h] [-o OPTIONAL [OPTIONAL ...]] [-p POS_WITH_DEFAULT]
Одно простое изменение в Help_Formatter - просто перечислить аргументы в том порядке, в котором они определены. Обычный способ изменения поведения форматирования заключается в подклассе и изменении одного или двух методов. Большинство из этих методов 'private' (_ prefix), поэтому вы делаете это с осознанием того, что будущий код может меняться (медленно).
В этом методе actions
- это список аргументов в том порядке, в котором они были определены. Поведение по умолчанию состоит в том, чтобы разделить "дополнительные параметры" на "позиционные элементы" и собрать список с позициями в конце. Там есть дополнительный код, который обрабатывает длинные строки, которые требуют обертывания. Обычно он позиционирует позиции на отдельной строке. Я пропустил это.
class Formatter(argparse.HelpFormatter):
# use defined argument order to display usage
def _format_usage(self, usage, actions, groups, prefix):
if prefix is None:
prefix = 'usage: '
# if usage is specified, use that
if usage is not None:
usage = usage % dict(prog=self._prog)
# if no optionals or positionals are available, usage is just prog
elif usage is None and not actions:
usage = '%(prog)s' % dict(prog=self._prog)
elif usage is None:
prog = '%(prog)s' % dict(prog=self._prog)
# build full usage string
action_usage = self._format_actions_usage(actions, groups) # NEW
usage = ' '.join([s for s in [prog, action_usage] if s])
# omit the long line wrapping code
# prefix with 'usage:'
return '%s%s\n\n' % (prefix, usage)
parser = argparse.ArgumentParser(formatter_class=Formatter)
Создает строку использования, например:
usage: stack26985650.py [-h] positional [-o OPTIONAL [OPTIONAL ...]]