Python argparse с подразделами и необязательными позиционными аргументами

#python #python-3.x #argparse

#python #python-3.x #argparse

Вопрос:

Я хотел бы иметь программу с подпараметрами, которая обрабатывает определенные аргументы, сохраняя при этом некоторые позиционные и необязательные аргументы для предыдущих парсеров (на самом деле мне действительно нужен только один вариант, я имею в виду, допустимый подпараметр ИЛИ допустимый локальный аргумент).

Пример того, что я хотел бы иметь: Program [{sectionName [{a,b}]}] [{c,d}] . Несовместимость с c / d, если было указано имя раздела и наоборот.

Однако лучшее, чего я мог добиться, это test.py [-h] {sectionName} ... [{c,d}] . Это означает, что argparse не позволяет мне использовать позиционные аргументы c или d без указания допустимого sectionName .

Вот код:

 import argparse

mainparser = argparse.ArgumentParser()
# Subparser
subparser = mainparser.add_subparsers(title="section", required=False)
subparser_parser = subparser.add_parser("sectionName")
subparser_parser.add_argument("attribute", choices=['a', 'b'], nargs='?')
# Main parser positional and optional attributes
mainparser.add_argument("attribute", choices=['c', 'd'], nargs='?')

mainparser.parse_args()
  

Я схожу с ума от этого. Любая помощь будет высоко оценена!

Редактировать: я использую Python 3.8

Ответ №1:

subparser Объект на самом деле является позиционным Action , тот, который принимает choices — в данном случае {'sectionName'} . positinal аргументы заполняются в том порядке, в котором они определены, с использованием nargs шаблона для выделения строк.

Как только основной анализатор получает ‘SectionName’, он передает синтаксический subparser_parser анализ. Than обрабатывает остальные входные данные, такие как {'a','b'} позиционные. Все, что он не может обработать, помещается в список «нераспознанных», и элемент управления возвращается main для окончательной обработки. main не выполняет никакой дальнейшей обработки аргументов. Таким образом, ваш attribute аргумент игнорируется.

Вы могли бы поставить определение attribute позиции перед add_subparsers , но я бы не стал пытаться это сделать nargs='?' .

Поэтому лучше всего определить все main аргументы перед подразделами и использовать optionals . Это даст самый чистый и надежный синтаксический анализ.

Комментарии:

1. Спасибо hpaulj за ваш ответ! Однако я хочу, чтобы эти позиционные аргументы были необязательными. Я имею в виду, что моя настоящая цель — использовать это в python cmd2, который использует argparse внутренне. Для этого команды должны иметь некоторый синтаксис, например: show interface или show interface interfaceName , чтобы они могли иметь позиционные значения (или нет) с несколькими уровнями подпараметрии. Некоторые команды требуют наличия необязательных аргументов, в то же время у них может быть некоторый подраздел для «сложных» позиционных значений. Возможный пример: show interface interfaceName onDevice xxx где onDevice находится разделитель, который обрабатывает разработчиков

2. Кроме того, я попытался изменить порядок команд с помощью разных require nargs опций и, но ни одна из них не приближается к тому, что я хочу:-(

3. Имейте в виду, что при разборе позиционных argparse значений работает строго по позиции, используя nargs сопоставление с шаблоном. Он не проверяет значения. choices Тестирование выполняется после выделения. В вашем примере он не ищет строку ‘d’ или ‘b’ или ‘SectionName’. Используется optionals для поиска определенных значений флага.

4. Думаю, я понимаю вашу точку зрения. Это не тот ответ, который я ожидал, но иногда есть ограничения, которые трудно преодолеть. Большое спасибо @hpaulj за ваше время.