Python Argparse - условно обязательные аргументы, основанные на значении другого аргумента - PullRequest
0 голосов
/ 30 августа 2018

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

python3 test.py -c start -d /mydownloadfolder/ -j /myconfig.json

чтобы остановить службу,

python3 test.py -c stop

Параметры -d -j требуются только при запуске службы. Поэтому мне нужно реализовать условно обязательные аргументы, основанные на значении другого аргумента.

Я провел некоторый поиск и нашел этот полезный пост Python Argparse условно обязательные аргументы Разница в том, что вместо проверки наличия --command мне нужно проверить значение --command.

Вот мое предварительное решение:

PARSER.add_argument('-c', '--command', required=True, help='provide a valid command: start, stop, restart, or status')
NEED_MORE_ARGS = PARSER.parse_args().command.lower().startswith('start')
PARSER.add_argument('-d', '--download', required=NEED_MORE_ARGS , default=LOCAL_DOWNLOAD, help='set account download folder')
PARSER.add_argument('-j', '--input',  required=NEED_MORE_ARGS, default=JSON_INPUT, help='set input json file')

Я проанализировал аргументы в середине, чтобы получить NEED_MORE_ARGS (логическое значение), а затем добавил другие аргументы. Код кажется не чистым. Есть ли лучший способ сделать это?

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

Обновлено: предварительное решение не работает. (

1 Ответ

0 голосов
/ 30 августа 2018

Я думаю, что вы можете использовать два парсера для этого:

import argparse

if __name__ == '__main__':
    command_parser = argparse.ArgumentParser()
    command_parser.add_argument('-c', '--command', required=True,
                                help='provide a valid command: start, stop, restart, or status')

    if command_parser.parse_known_args()[0].command.lower().startswith('start'):
        option_parser = argparse.ArgumentParser()
        option_parser.add_argument('-d', '--download', required=True, help='set account download folder')
        option_parser.add_argument('-j', '--input', required=True, help='set input json file')
        option_parser.parse_known_args()

или вы можете использовать подпарсер, что, вероятно, лучше в вашем случае:

import argparse

if __name__ == '__main__':
    command_parser = argparse.ArgumentParser()

    subparsers = command_parser.add_subparsers(help='Choose a command')

    start_parser = subparsers.add_parser('start', help='"start" help')
    start_parser.add_argument('-d', '--download', required=True, help='set account download folder')
    start_parser.add_argument('-j', '--input', required=True, help='set input json file')
    start_parser.set_defaults(action=lambda: 'start')

    stop_parser = subparsers.add_parser('stop', help='"stop" help')
    stop_parser.set_defaults(action=lambda: 'stop')

    command_parser.parse_args()

в этом случае синтаксис командной строки будет немного другим:

python3 test.py start -d /mydownloadfolder/ -j /myconfig.json

python3 test.py stop
...