Сначала я думал так же, как 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
получает два аргумента, aИ, конечно же, он заканчивается удушением.
Достаточно забавно, шаблон для nargs='+'
равен '(-*A[-AO]*)(-*A[A-]*)'
, который работает , если вы передаете только один аргумент .Скажите subpositional a
, так как вам требуется хотя бы один позиционный аргумент во второй группе.Опять же, поскольку первая группа жадная, пропуск subpositional a b c d
дает вам ['AAAA', 'A']
, а это не то, что вы хотели.
Вкратце: беспорядок.Я думаю, это следует считать ошибкой, но я не уверен, какое влияние это окажет, если шаблоны превратятся в не жадных ...