我正在使用Argparser来处理我的CLI编程的参数。但随着时间的推移,我认为使用它并不是一个好主意。这就是问题所在。我想使用没有任何前缀字符的选项。比如 git commit 或 svn move 。我搜索了一下,发现Argparse有一个add_subparser()方法。让我们填充 foo prog:
parser = argparse.ArgumentParser(prog='foo', usage='%(prog)s [options]')
subparsers = parser.add_subparsers(help='sub-command help')
parser_a = subparsers.add_parser('add', help='a help')
parser_a.add_argument('-ap', '--add-project',
nargs='*',
action='store',
help="Add project")
parser_d = subparsers.add_parser('del', help='a help')
parser_d.add_argument('-dp', '--delete-project',
nargs='*',
action='store',
help="Delete project")
args = parser.parser_args()
现在让我们使用选项执行foo并打印args
命名空间(我没有过去整个代码,你明白了):
$ ./foo del
Namespace(delete_project=None)
$ ./foo add
Namespace(add_project=None)
如您所见,如果我执行选项del
,则 add_project 不会传递给变量args
。如果我的main()函数中有“if子句”,如
def main(args):
if args.delete_project:
...
if args.add_project:
...
我将获得 AttributeError 异常,如果我执行./foo del
,则命名空间没有名称为 add_project 的属性。除此之外,我无法将任何参数传递给选项del
和add
。我还将prefix_chars设置为空字符串,这也不起作用。
处理它的方法是什么? argparse是否能够创建像git,svn等选项..或者我应该创建自己的函数并自己处理所有参数?
答案 0 :(得分:0)
修改:显然default
的默认设置为None
,这意味着我们没有True
,因此您必须使用False
和default
(其中无论如何都是正确的方式。)
将参数添加到解析器时,需要添加parser_a.add_argument('-ap', '--add-project',
nargs = '*',
action = 'store_true',
default = False,
help = "Add project")
:
add_argument
您可以查看argparse
方法here的文档。 (我意识到try:
doc布局不是最有助于弄清楚如何处理示例中没有提到的事情)
此外,正如Tobu在他的回答中正确指出的那样,未使用的子分析器不会被调用,因此您无法安全地探测其值,而不至少保护action
块中的代码。但是,实际上您应该使用将{{1}}与子分析符相关联的功能,除非您有一个更复杂的情况需要共享状态。
答案 1 :(得分:0)
而不是if语句,the argparse docs recommend something like this:
parser_X.set_defaults(action=action_func)
args.action(args)
然后add_action将在del_project中查看add_project和del_action。