Сначала я думал так же, как jcollado, но есть тот факт, что, если последующие (верхний уровень) позиционные аргументы имеют специфический nargs
(nargs
= None
, nargs
= целое число), то она работает, как вы ожидаете. Он терпит неудачу, когда nargs
равно '?'
или '*'
, а иногда, когда это '+'
. Итак, я пошел к коду, чтобы выяснить, что происходит.
Это сводится к тому, что аргументы разделены на потребление. Чтобы выяснить, кто что получает, вызов parse_args
суммирует аргументы в строке, например 'AA'
, в вашем случае ('A'
для позиционных аргументов, 'O'
для необязательных) и заканчивается созданием шаблона регулярного выражения, который будет соответствовать этой суммарной строке, в зависимости от о действиях, которые вы добавили в парсер с помощью методов .add_argument
и .add_subparsers
.
В каждом случае, например, строка аргументов заканчивается 'AA'
. Какие изменения соответствуют шаблону (вы можете увидеть возможные шаблоны под _get_nargs_pattern
в argparse.py
. Для subpositional
он заканчивается '(-*A[-AO]*)'
, что означает, что разрешает один аргумент, за которым следует любое количество опций или аргументов.Для positional
, это зависит от величины переданного nargs
:
None
=>'(-*A-*)'
- 3 =>
'(-*A-*A-*A-*)'
(один '-*A'
за ожидаемого аргумента)
'?'
=>'(-*A?-*)'
'*'
=>'(-*[A-]*)'
'+'
=>'(-*A[A-]*)'
Эти модели добавляются и для nargs=None
(ваш рабочий пример), вы в конечном итоге с '(-*A[-AO]*)(-*A-*)'
, который соответствует две группы ['A', 'A']
. Таким образом, subpositional
будет анализировать только subpositional
(что вам нужно), а positional
будет соответствовать его действию.
Для nargs='?'
, однако, вы получите '(-*A[-AO]*)(-*A?-*)'
. Вторая группа целиком состоит из необязательных узоров, а *
является жадным, это означает, что первая группа глотает все в строке, заканчивая распознаванием двух групп ['AA', '']
. Это означает, что subpositional
получает два аргумента и, конечно же, заканчивает удушение.
Забавно, что шаблон для nargs='+'
- '(-*A[-AO]*)(-*A[A-]*)'
, который работает , если вы передаете только один аргумент. Скажите subpositional a
, так как вам требуется хотя бы один позиционный аргумент во второй группе. Опять же, поскольку первая группа жадна, минуя subpositional a b c d
, вы получаете ['AAAA', 'A']
, что не то, что вы хотели.
Вкратце: беспорядок. Я думаю, это должно рассматриваться как ошибка, но не уверен, что влияние будет, если шаблоны включены в нежадным те ...
Btw, кажется, [известная ошибка ] (http://bugs.python.org/issue9340), который был исправлен для последних версий Python. –