我正在编写一个能够执行多个子命令的程序。more解析模块非常有用,但我认为它缺乏指定多个子命令的能力。例如,如果我有以下代码:
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。我一次只能做一个。我想这将需要一个自定义操作,甚至可能需要子类a解析,但我不知道从哪里开始。我希望能够像下面这样调用这个程序:
./prog.py subcommand_a FOO --opt1=bar --opt2 1 2 3 -- subcommand_b BAR --opt1='foo' --opt3 a b c --有什么想法吗?
发布于 2014-08-15 02:07:37
你的问题与几个月前提出的问题基本相同。
它想要多次调用同一个子命令,但问题是相同的--如何处理多个subparsers参数。
其中的解决方案要么是在将命令行以单独解析的方式传递之前将其拆分,要么从一个解析中收集“未使用的”片段,以便在第二个或第三个解析中使用。
下面对返回两个命令的代码进行调整:
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‘结束,第二个命令没有留下任何值。有关问题和解决方法的讨论,请参阅另一条线索。
发布于 2014-08-14 22:57:54
我做了一些测试,并将子命令更改为其他字符串。如果你使用:
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()它起作用了。
我已经做了一些研究,但没有找到一个具有相同字符串的子命令。对文档的概述也不为过。我认为这是一个限制(选择)或一个错误。也许你可以在源代码托管上检查一下
https://stackoverflow.com/questions/25318622
复制相似问题