Nano Hash - криптовалюты, майнинг, программирование

Как выполнять argparse с помощью nargs+ и подкоманд

Я пытаюсь создать команду типа

prog [-h] [-i ID [ID ...]] | -x [SOMETHING] 
     {cmd1,cmd2,cmd3}...

Итак, в основном на верхнем уровне у меня есть синтаксический анализатор, который имеет взаимную исключающую группу для параметров -i и -x, а затем, следуя этим (и, возможно, другим) параметрам, у меня есть команда, которую я хочу запустить. Каждая команда имеет свой собственный набор параметров, которые они используют. Я могу заставить команды нормально работать с add_subparsers(), но проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь добавить аргумент в корневой синтаксический анализатор, который имеет nargs='+'. Когда я это делаю, он проглатывает все аргументы для -i, думая, что команда является аргументом, а не идентификатором.

Есть ли способ обойти это? Похоже, что ему придется просматривать аргументы -i в поисках командного слова, а затем сообщать argparse, что с этого момента следует возобновить синтаксический анализ.

19.01.2017

  • можете ли вы показать нам минимальный воспроизводимый пример/ваш код, если он не слишком велик? 19.01.2017
  • Оформите Click для создания интерфейсов командной строки с помощью python и избавьте себя от головной боли. 19.01.2017
  • @garnertb +1. Могу подтвердить, click великолепен и очень хорошо обрабатывает подкоманды. 19.01.2017

Ответы:


1

Мне пришлось прочитать ваше описание несколько раз, но я думаю, что это проблема:

prog -i id1 id2 cmd1 -foo 3 ....

и это дает какое-то предупреждение о том, что {cmd1,cmd2,cmd3} не найдено. Точная ошибка может отличаться, потому что в некоторых версиях subparsers на самом деле не требуется.

В любом случае аргументы -i равны ['id1','id2','cmd1'], все до следующего флага -. Для основного парсера аргумент подпарсеров — это просто еще один аргумент positionalchoices). При размещении строк в -i не проверяется соответствие строки одному из cmds. Он просто смотрит, начинается ли он с - или нет.

Единственный способ использовать nargs='+' (или '*') в контексте - это включить какой-либо другой помеченный аргумент, например.

prog -i id1 id2 -x 3 cmd1 --foo ...

Я понимаю, что это противоречит вашей группе mutually_exclusive.

Основная идея заключается в том, что строки без флагов выделяются на основе позиции, а не значения. Для переменной nargs у вас должен быть какой-то явный признак конца списка.

С боковой панели

Argparse nargs=+ потребляет позиционный аргумент

Это похоже, за исключением того, что ваша следующая позиция — это cmd подпарсеров.

==============

Позиция с «+» будет работать прямо перед командной строкой подпарсера.

usage: prog [-h] foo [foo ...] {cmd1,cmd2} ...

In [160]: p1.parse_args('1 22 3 cmd1'.split())
Out[160]: Namespace(cmd='cmd1', foo=['1', '22', '3'])

Но это потому, что строки для foo и cmd выделяются одним тестом шаблона regex.

In

usage: prog [-h] [--bar BAR [BAR ...]] {cmd1,cmd2} ...

строки распределяются по bar без привязки к потребностям следующего позиционного, cmd. Как показано в предлагаемых исправлениях для http://bugs.python.org/issue9338, изменение этого поведения не тривиальное изменение. Для этого требуется дополнительный цикл проб и ошибок.

19.01.2017
  • Как следствие этого: nargs='+' обычно плохо ладит с другими. Либо используйте один аргумент несколько раз (-i id1 -i id2 cmd1), либо определите параметр, чтобы принимать один анализируемый аргумент (-i id1,id2 cmd1). 19.01.2017
  • Да, это простое решение, которое я придумал, но оно не идеально. Я хотел бы, чтобы он был достаточно умен, чтобы знать, что команды являются опциями, и продолжать синтаксический анализ, не зная секретного соуса создания списка, разделенного запятыми, -- и т. д. В идеале синтаксический анализатор должен проверять id2 и понимать, что это команда и анализ как таковой. По сути, я хочу посмотреть следующий идентификатор. Если не в командах, добавьте к идентификаторам, иначе проанализируйте как команду 19.01.2017
  • Это противоречит основному методу анализа argparse. optparse может делать что-то вроде того, что вы хотите. Но argparse работает исключительно из строк позиции и флага. Он не «упреждает», чтобы увидеть, соответствует ли следующая строка некоторым критериям значения. Сначала он выделяет строки для действия, а затем запускает тесты type и choices, а не наоборот. 19.01.2017
  • Я добавил ссылку на проблему с ошибкой, которая пытается реализовать своего рода предвидение. 20.01.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..