我试图编写一个能够执行多个子命令的程序。 argparse模块非常有用,但我认为它缺乏指定多个子命令的能力。例如,如果我有以下代码:
parser = argparse.ArgumentParser(prog='My Prog')
sub_parsers = parser.add_subparsers()
subcommand_a = sub_parsers.add_parser('subcommand_a', help='a help')
subcommand_a.add_argument('req1', help='required argument 1 help')
subcommand_a.add_argument('--opt1', help='option 1 help')
subcommand_a.add_argument('--opt2', nargs='+', help='option 2 help')
subcommand_b = sub_parsers.add_parser('subcommand_b', help='b help')
subcommand_b.add_argument('req1', help='required argument 1 help')
subcommand_b.add_argument('--opt1', help='option 1 help')
subcommand_b.add_argument('--opt2', help='option 2 help')
subcommand_b.add_argument('--opt3', nargs='+', help='option 3 help')
parser.parse_args()
我无法在命令行上同时指定subcommand_a和subcommand_b。我一次只能做其中一个。我想象这需要一个自定义动作,甚至可能是argparse的子类,但我不知道从哪里开始。我希望能够像以下一样调用此程序:
./prog.py subcommand_a FOO --opt1=bar --opt2 1 2 3 -- subcommand_b BAR --opt1='foo' --opt3 a b c --
有什么想法吗?
答案 0 :(得分:2)
你的问题与几个月前提出的问题基本相同
Multiple invocation of the same subcommand in a single command line
那个想要多次调用相同的子命令,但问题是相同的 - 如何处理多个subparsers
参数。
那里的解决方案是将命令行拆分,然后将其分别解析,或者从一次解析中收集“未使用的”部分,以便在第二个或第三个中使用。
这里调整了返回2个命令的代码:
import argparse
parser = argparse.ArgumentParser(prog='My Prog')
sub_parsers = parser.add_subparsers(dest='cmd')
subcommand_a = sub_parsers.add_parser('subcommand_a', help='a help')
subcommand_a.add_argument('req1', help='required argument 1 help')
subcommand_a.add_argument('--opt1', help='option 1 help')
subcommand_a.add_argument('--opt2', nargs=3, help='option 2 help')
subcommand_b = sub_parsers.add_parser('subcommand_b', help='b help')
subcommand_b.add_argument('req1', help='required argument 1 help')
subcommand_b.add_argument('--opt1', help='option 1 help')
subcommand_b.add_argument('--opt2', help='option 2 help')
subcommand_b.add_argument('--opt3', nargs=3, help='option 3 help')
argv = "subcommand_a FOO --opt1=bar --opt2 1 2 3 subcommand_b BAR --opt1=foo --opt3 a b c"
rest = argv.split()
while rest:
[args, rest] = parser.parse_known_args(rest)
print args
print rest
打印:
Namespace(cmd='subcommand_a', opt1='foo', opt2=['1', '2', '3'], req1='FOO')
['subcommand_b', 'BAR', '--opt3', 'a', 'b', 'c']
Namespace(cmd='subcommand_b', opt1=None, opt2=None, opt3=['a', 'b', 'c'], req1='BAR')
[]
我删除了'--'
(请参阅我的其他答案的结尾)
我更改了opt2
和opt3
以获取3个参数,而不是变量+
。使用+
时,无法确定opt2
列表的结束位置以及下一个命令的开始位置。
不同的命令采用不同的选项(标志)也很重要。请注意,第一个opt1
以第二个值'foo'结束,第二个命令没有。请参阅另一个主题,讨论问题及其解决方法。
答案 1 :(得分:0)
我做了一些测试,并将子命令更改为其他字符串。 如果您使用:
parser = argparse.ArgumentParser(prog='My Prog')
sub_parsers = parser.add_subparsers()
subcommand_a = sub_parsers.add_parser('subcommand_a', help='a help')
subcommand_a.add_argument('req1', help='required argument 1 help')
subcommand_a.add_argument('--opt1', help='option 1 help')
subcommand_a.add_argument('--opt2', nargs='+' help='option 2 help')
subcommand_b = sub_parsers.add_parser('subcommand_b', help='b help')
subcommand_b.add_argument('req1', help='required argument 1 help')
subcommand_b.add_argument('--opt3', help='option 1 help')
subcommand_b.add_argument('--opt4', help='option 2 help')
subcommand_b.add_argument('--opt5', nargs='+', help='option 3 help')
parser.parse_args()
它有效。
我做了一些研究,没有找到一个字符串相等的子命令。文档概述也没有说明。我认为这是一个限制(通过选择)或一个错误。 也许你可以在Source Code Hosting
中查看