Укажите множество опций в argparse, используя *

У меня вопрос к вам! Я разработал инструменты командной строки со множеством опций, используя argparse. Вот упрощенная версия того, что у меня есть:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--skip-part1', action='store_true', default=False)
parser.add_argument('--skip-part2', action='store_true', default=False)
parser.add_argument('--skip-part3', action='store_true', default=False)
parser.add_argument('--skip-part4', action='store_true', default=False)

Я бы хотел, чтобы пользователь мог выбрать все необязательные аргументы пропуска, набрав что-то вроде

myscript.py --skip-*

Еще более продвинутый вариант, используя регулярное выражение:

myscript.py --skip-part[1-3]

чтобы выбрать только первые три варианта.

Знаете ли вы, как я мог добиться такого поведения?

Спасибо

в argparse таких ярлыков нет.

hpaulj 14.09.2023 15:23

выглядит то, что вы хотите, это дополнительный аргумент --skip-part, а затем анализируйте и объясняйте значение так, как вам нравится: --skip-part '[1-3]', --skip-part '*', ...

exudong 14.09.2023 15:25

Существует параметрallow-abbrev, который определяет, ожидает ли он точного совпадения флагов или просто однозначных сокращений.

hpaulj 14.09.2023 15:32

Это можно сделать, выполнив шаг расширения (с помощью fnmatch) до sys.argv перед вызовом анализатора аргументов. Смотрите мой ответ.

fferri 14.09.2023 16:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете попробовать что-то вроде этого:

parser.add_argument('--skip', action='store', default=None, nargs=1) # nargs = 1 means that 1 argument is accepted

Когда вы назовете что-то вроде myscript.py --skip 1-3args.skip == ["1-3"], это будет правдой. Итак, вы получаете список с одной строкой. С этой строкой вы можете делать все, что захотите. Вы можете разделить его на «-», чтобы получить начало и конец примера.

Мне очень нравится это решение, оно не сильно усложняет структуру кода и доводит до сути.

toto 14.09.2023 17:18

argparse требует статически определенных имен опций.

Однако вы можете выполнить предварительную обработку sys.argv для выполнения любого типа расширения самостоятельно, а затем вызвать parse_args():

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--skip-part1', action='store_true', default=False)
parser.add_argument('--skip-part2', action='store_true', default=False)
parser.add_argument('--skip-part3', action='store_true', default=False)
parser.add_argument('--skip-part4', action='store_true', default=False)

# expand sys.argv:
import sys
import fnmatch
all_options = [opt
               for a in parser._actions
               for opt in a.option_strings
              ]
new_argv = []
for arg in sys.argv:
    matched = False
    for opt in all_options:
        if fnmatch.fnmatch(opt, arg):
            matched = True
            new_argv.append(opt)
    if not matched:
        new_argv.append(arg)
sys.argv = new_argv

print(parser.parse_args())

сейчас проходящий --skip-part[1-3] вернет тебя Namespace(skip_part1=True, skip_part2=True, skip_part3=True, skip_part4=False) и нажатие --skip-* активирует все соответствующие переключатели.

Другие вопросы по теме