#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 за ваше время.