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

Рассмотрим следующее использование:

usage: do.py [-h] [-s | -m] filename

Это не полное использование. Но я эффективно хочу это filename быть действительным значением файла, а не:

--filename FILENAME

Но также, filename должен быть необязательным, чтобы я мог читать со стандартного ввода. Думать о cat программа на UNIX.

Вы просто говорите:

cat filename

ИЛИ ЖЕ

cat

РЕДАКТИРОВАТЬ: Прямо сейчас, если я выполню программу do.py без каких-либо параметров командной строки, я получу error: too few arguments, Вместо этого я все еще хотел бы, чтобы это выполнялось, даже если я не даю это действительное filename, Как я могу это сделать?

1 ответ

Решение

Обновление 2: из документации ArgParse,

Одно из наиболее распространенных применений nargs='?' это разрешить необязательные входные и выходные файлы:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
...                     default=sys.stdin)
>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
...                     default=sys.stdout)
>>> parser.parse_args(['input.txt', 'output.txt'])
Namespace(infile=<open file 'input.txt', mode 'r' at 0x...>,
          outfile=<open file 'output.txt', mode 'w' at 0x...>)
>>> parser.parse_args([])
Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>,
          outfile=<open file '<stdout>', mode 'w' at 0x...>)

Оригинальный ответ:

Это просто: просто добавьте позиционный аргумент со значением по умолчанию и nargs='*', Значение по умолчанию будет использоваться при нулевых аргументах, в противном случае будут использоваться аргументы в командной строке:

>>> p = argparse.ArgumentParser()
>>> p.add_argument('filename', nargs='*', default=['-'])
>>> p.parse_args([])
Namespace(filename=['-'])
>>> p.parse_args(['abc'])
Namespace(filename=['abc'])

Как правило, - используется для обозначения стандартного ввода / стандартного вывода.

Затем вы делаете что-то вроде этого:

def get_inputs(ns):
    """Iterate over input files."""
    for path in ns.filename:
        if path == '-':
            yield sys.stdin
        else:
            yield open(path, 'r')

Обновление: я предположил, что вы хотели несколько имен файлов, так как cat занимает несколько имен файлов. Ты можешь использовать nargs='?' если вы хотите либо ноль, либо одно имя файла.

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