使用 parse_known_args 一次解析多个子命令
Parsing multiple subcommands at once using parse_known_args
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='config command help')
# create parser for config command
parser_config = subparsers.add_parser('config', help='config help')
parser_config.add_argument('--configname', required=True, nargs=1)
parser_config.add_argument('--login', required=True, nargs=1)
parser_config.add_argument('--password', required=True, nargs=1)
parser_config1 = subparsers.add_parser('config1', help='config help')
parser_config1.add_argument('--configname', required=True, nargs=1)
parser_config1.add_argument('--login', required=True, nargs=1)
parser_config1.add_argument('--password', required=True, nargs=1)
rest = 'config --configname name1 --login abc1 --password def1 config1 --configname name2 --login abc2 --password def2'.split()
print(rest)
while rest:
args,rest = parser.parse_known_args(rest)
argslist.append(args)
print(args, rest)
给出:
$ python3 create_config.py
['config', '--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name2'], login=['abc2'], password=['def2']) ['config1'] [Namespace(configname=['name2'], login=['abc2'], password=['def2'])]
usage: create_config.py config1 [-h] --configname CONFIGNAME --login LOGIN
--password PASSWORD
create_config.py config1: error: the following arguments are required: --configname, --login, --password
我希望看到
['config', '--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name1'], login=['abc1'], password=['def1']) ['config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name2'], login=['abc2'], password=['def2']) []
我怎样才能做到这一点?
config
子解析器得到:
['--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
它解析
['--configname', 'name1', '--login', 'abc1', '--password', 'def1']
符合预期。然后它看到 config1
,它无法处理(没有 positionals
)。它把它放在 extras
列表中,并继续解析其余的
['--configname', 'name2', '--login', 'abc2', '--password', 'def2']
这会覆盖之前的 optional's
值,这就是您最终在 args
中看到的值。
我认为如果两个子解析器采用不同的标志,那么这种方法会奏效。我认为在您上一个问题的链接中探讨了此类问题,但我必须研究它们才能确定。
无论如何,parse_known_args
不会在遇到无法解析的字符串时就退出。与常规 parse_args
一样,它会尝试处理整个列表,只是 returns 将剩余的作为列表而不是引发错误。并且允许重复可选,即使它们没有任何用处(除非定义为 append
操作)。
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='config command help')
# create parser for config command
parser_config = subparsers.add_parser('config', help='config help')
parser_config.add_argument('--configname', required=True, nargs=1)
parser_config.add_argument('--login', required=True, nargs=1)
parser_config.add_argument('--password', required=True, nargs=1)
parser_config1 = subparsers.add_parser('config1', help='config help')
parser_config1.add_argument('--configname', required=True, nargs=1)
parser_config1.add_argument('--login', required=True, nargs=1)
parser_config1.add_argument('--password', required=True, nargs=1)
rest = 'config --configname name1 --login abc1 --password def1 config1 --configname name2 --login abc2 --password def2'.split()
print(rest)
while rest:
args,rest = parser.parse_known_args(rest)
argslist.append(args)
print(args, rest)
给出:
$ python3 create_config.py
['config', '--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name2'], login=['abc2'], password=['def2']) ['config1'] [Namespace(configname=['name2'], login=['abc2'], password=['def2'])]
usage: create_config.py config1 [-h] --configname CONFIGNAME --login LOGIN
--password PASSWORD
create_config.py config1: error: the following arguments are required: --configname, --login, --password
我希望看到
['config', '--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name1'], login=['abc1'], password=['def1']) ['config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name2'], login=['abc2'], password=['def2']) []
我怎样才能做到这一点?
config
子解析器得到:
['--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
它解析
['--configname', 'name1', '--login', 'abc1', '--password', 'def1']
符合预期。然后它看到 config1
,它无法处理(没有 positionals
)。它把它放在 extras
列表中,并继续解析其余的
['--configname', 'name2', '--login', 'abc2', '--password', 'def2']
这会覆盖之前的 optional's
值,这就是您最终在 args
中看到的值。
我认为如果两个子解析器采用不同的标志,那么这种方法会奏效。我认为在您上一个问题的链接中探讨了此类问题,但我必须研究它们才能确定。
无论如何,parse_known_args
不会在遇到无法解析的字符串时就退出。与常规 parse_args
一样,它会尝试处理整个列表,只是 returns 将剩余的作为列表而不是引发错误。并且允许重复可选,即使它们没有任何用处(除非定义为 append
操作)。