Python Argparse-基于另一个参数的值的条件必需参数

时间:2018-08-29 21:50:34

标签: python argparse

我正在尝试编写一个守护程序服务,可以在命令行中对其进行控制。例如,启动服务

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

要停止服务,

python3 test.py -c stop

仅在启动服务时才需要-d -j参数。因此,我需要根据另一个参数的值来实现有条件的参数。

我进行了一些搜索,发现这篇有用的帖子Python Argparse conditionally required arguments 区别在于:我需要检查'--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(boolean),然后添加其他参数。该代码似乎不干净。有更好的方法吗?

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

已更新:暂定解决方案不起作用。 :(

1 个答案:

答案 0 :(得分:2)

我认为您可以使用两个解析器来做到这一点:

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