Python argparse,运行一个或多个子命令 [英] Python argparse, run one or more sub-commands
问题描述
我正在尝试编写一个能够执行多个子命令的程序.argparse 模块非常有用,但我认为它缺乏指定多个子命令的能力.例如,如果我有以下代码:
I'm trying to write a program that is able to execute multiple sub-commands. The argparse module is very helpful, but I think it is lacking the ability to specify more than one sub-command. For example, if I have the following code:
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 进行子类化,但我不确定从哪里开始.我希望能够像下面这样调用这个程序:
I cannot specify both subcommand_a and subcommand_b on the command line. I can only do one of them at a time. I'd imagine that this would require a custom action or possibly even subclassing argparse, but I'm not sure where to start. I'd like to be able to call this program like the following:
./prog.py subcommand_a FOO --opt1=bar --opt2 1 2 3 -- subcommand_b BAR --opt1='foo' --opt3 a b c --
有什么想法吗?
推荐答案
你的问题和几个月前问的问题基本一样
Your problem is essentially the same as the one asked a few months back
那个人想多次调用同一个子命令,但问题是一样的 - 如何处理多个 subparsers
参数.
That one wanted to call the same subcommand several times, but the issue the same - how to handle more than one subparsers
argument.
那里的解决方案要么是在将命令行分成单独解析的片段之前将其拆分,要么从一次解析中收集未使用"的片段以供第二次或第三次使用.
The solutions there are either to split the command line before passing it in pieces that are parsed separately, or collect the 'unused' pieces from one parsing for using in a second or third.
这是对返回 2 个命令的代码的调整:
Here's tweak to your code that returns 2 commands:
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')
[]
我删除了'--'
(见我其他答案的结尾)
I removed the '--'
(see the end of my other answer)
我将 opt2
和 opt3
更改为采用 3 个参数,而不是变量 +
.使用 +
它无法判断 opt2
的列表在哪里结束和下一个命令开始.
I changed opt2
and opt3
to take 3 arguments, not the variable +
. With +
it can't tell where the list for opt2
ends and the next command begins.
不同的命令采用不同的选项(标志)也很重要.请注意,第一个 opt1
以第二个值 'foo' 结束,第二个命令没有留下任何值.有关问题和解决方法的讨论,请参阅另一个线程.
It is also important that the different commands take different optionals (flags). Note that the first opt1
ends up with the second value, 'foo', leaving none for the 2nd command. See the other thread for a discussion of the issues and ways around that.
这篇关于Python argparse,运行一个或多个子命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!