Argparse Python 3 аргументы меняющие режим работы программы

Мой скрипт на python имеет 2 режима работы, первый режим работы это загрузка файла, второй режим работы это отдача файла (выгрузка).

Скрипт принимает 3 аргументы, и 2 из них собственно определяют режим его работы.

Аргумент -L определяет ссылку на файл который надо загрузить (следовательно запускает режим загрузки).

Аргумент -F определяет имя файла который нужно будет отдавать (следовательно запускает режим выгрузки).

Помимо прочего, если режим работы - это выгрузка файла, скрипт должен принимать аргумент -P, который определит номер TCP порта, который будет открыт для выгрузки файла. Собственно вопрос в том, как правильно парсить аргументы, чтобы если в аргументах есть аргумент -L, то мы не ждали больше никаких аргументов, а сразу запустили загрузку, а если же есть аргумент -F (или -P, их же не обязательно в одном порядке передавать), то мы ожидаем еще и аргумент -P, и запускаем выгрузку ?


Ответы (1 шт):

Автор решения: alex

Никаких if-ов.

import argparse


def parse_args():
    parser = argparse.ArgumentParser()

    subparsers = parser.add_subparsers(dest='command')
    cmd_a = subparsers.add_parser('cmd_a', description="Описание команды cmd_a")
    cmd_a.add_argument('name', type=str, help='Обязательный аргумент cmd_a')

    cmd_b = subparsers.add_parser('cmd_b', description="Описание команды cmd_b")
    cmd_b.add_argument('path', type=str, help='Обязательный аргумент cmd_b')
    cmd_b.add_argument('--noop', action='store_true', help='Опциональный флаг для cmd_b')

    args = parser.parse_args()
    return args


command_map = {}


def command(name=None, **kwargs):

    def wrapped(fun):
        command_map[name or fun.__name__] = fun
        return fun

    return wrapped


@command(name="cmd_a")
def download(name, **kwargs):
    """Описание команды cmd_a"""
    print('downloading', name, kwargs)


@command(name="cmd_b")
def upload(path, noop=False, **kwargs):
    """Описание команды cmd_b"""
    print('downloading', path, noop, kwargs)


def main():
    parsed_args = parse_args()
    command_map[parsed_args.command](**dict(parsed_args._get_kwargs()))


if __name__ == '__main__':
    main()

$ ./arg_example.py --help

usage: arg_example.py [-h] {cmd_a,cmd_b} ...

positional arguments:
  {cmd_a,cmd_b}

optional arguments:
  -h, --help     show this help message and exit
$ ./arg_example.py cmd_a --help 
usage: arg_example.py cmd_a [-h] name

Описание команды cmd_a

positional arguments:
  name        Обязательный аргумент cmd_a

optional arguments:
  -h, --help  show this help message and exit
$ ./arg_example.py cmd_a WoW 
downloading WoW {'command': 'cmd_a'}
$ ./arg_example.py cmd_b --help
usage: arg_example.py cmd_b [-h] [--noop] path

Описание команды cmd_b

positional arguments:
  path        Обязательный аргумент cmd_b

optional arguments:
  -h, --help  show this help message and exit
  --noop      Опциональный флаг для cmd_b
$ ./arg_example.py cmd_b 420
downloading 420 False {'command': 'cmd_b'}
→ Ссылка