Подтвердить что ты не робот

Python: необязательные аргументы argparse без тире

Я хотел бы иметь следующий синтаксис:

python utility.py file1 FILE1 file2 FILE2

где file1 и file2 являются необязательными аргументами. Это легко заставить работать с этим синтаксисом:

python utility.py --file1 FILE1 --file2 FILE2

используя

parser.add_argument('--file1',type=file)
parser.add_argument('--file2',type=file)

однако, если я удаляю тире, argparse начинает интерпретировать его как позиционный, а не необязательный аргумент...

Другими словами, можно ли конкретно указать argparse, является ли аргумент необязательным или позиционным, чтобы у меня были необязательные параметры без тире?

4b9b3361

Ответ 1

Невозможно получить argparse для этого. Тем не менее, вы можете сделать argparse принимать любое количество позиционных аргументов:

parser.add_argument('FILES',nargs='*')
options=parser.parse_args()
file1,optional_files=options.FILES[0],options.FILES[1:]

Конечно, вы можете добавить некоторые проверки, чтобы удостовериться, что было указано не менее 1 файла и т.д.

ИЗМЕНИТЬ

Я все еще не уверен на 100%, что вы хотите здесь, но если file1 и file2 являются литеральными строками, вы можете немного обойти это путем предварительной обработки sys.argv. Конечно, это будет по-прежнему форматировать ваше справочное сообщение странно, но вы всегда можете добавить эпилог, объясняющий, что любая форма в порядке:

import argparse
import sys

mangle_args=('file1','file2')
arguments=['--'+arg if arg in mangle_args else arg for arg in sys.argv[1:]]

parser=argparse.ArgumentParser()
parser.add_argument('--file1')
parser.add_argument('--file2')
options=parser.parse_args(arguments)

Ответ 2

Другой пример будет:

train.py

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Arguments for wake_word")
    parser.add_argument('data', type=str, help="path to data")
    parser.add_argument('output', type=str, help="model save path")
    parser.add_argument('batch_size', type=int, help="batch size")
    parser.add_argument('epochs', type=int, help="no.s of epochs")
    args = parser.parse_args()
print(args.data + args.output + args.batch_size + args.epochs)

тогда вы можете просто запустить этот код с аргументами без тире

train.py /path/to/data/ /path/to/output_files/ 128 100

И в порядке возрастания

Ответ 3

Была такая же проблема. Мой обходной путь:

lastarg = sys.argv[-1]
if len(sys.argv) > 1 and lastarg[0] != '-':
    sys.argv[-1] = '-file'
    sys.argv.append(lastarg)

argparser = argparse.ArgumentParser()
argparser.add_argument('-d', action='store_true')
argparser.add_argument('-nrv', action='store_true')
argparser.add_argument('-file', type=str, default='')
args = argparser.parse_args()