2011-11-23 80 views
107

我认为这一定很容易,但我不明白。argparse:确定使用哪个子分析器

假设我有以下arparse解析器:

import argparse 

parser = argparse.ArgumentParser(version='pyargparsetest 1.0') 
subparsers = parser.add_subparsers(help='commands') 

# all 
all_parser = subparsers.add_parser('all', help='process all apps') 

# app 
app_parser = subparsers.add_parser('app', help='process a single app') 
app_parser.add_argument('appname', action='store', help='name of app to process') 

我怎么能确定,使用为子分析器? 电话:

print parser.parse_args(["all"]) 

给我一个空的命名空间:

Namespace() 
+0

这个问题恕我直言有更好的回答则认为一个原。 –

回答

56

编辑:请参阅quornian's answer这个问题,这是比我的好,应该是公认的答案。

根据argparse documentationparser.parse_args(...)的结果将“只包含主分析器和被选择的子分析器的属性”。不幸的是,这可能不足以确定使用哪个子分析器。文档建议在子解析器上使用set_defaults(...)方法来解决此问题。

例如,我已经添加了调用set_defaults()到您的代码:

import argparse 

parser = argparse.ArgumentParser(version='pyargparsetest 1.0') 
subparsers = parser.add_subparsers(help='commands') 

# all 
all_parser = subparsers.add_parser('all', help='process all apps') 
all_parser.set_defaults(which='all') 

# app 
app_parser = subparsers.add_parser('app', help='process a single app') 
app_parser.add_argument('appname', action='store', help='name of app to process') 
app_parser.set_defaults(which='app') 

现在,如果你运行

print parser.parse_args(["all"]) 

结果是

Namespace(which='all') 

退房的add_subparsers()有关更多信息和另一个示例的文档。

+5

'set_defaults'很有用,就像在文档中使用它将子命令绑定到一个函数的例子一样..但是add_parser(dest ='which')似乎是“正确”的方法,因为它不需要重复子命令名称 – dbr

+1

@dbr是的,你是对的。夸尔尼安的答案应该是公认的答案。 – srgerg

+0

@dbr,应该是'add_subparsers(dest ='which')' – smac89

202

一个更简单的解决方案是将dest添加到add_subparsers调用。这是埋位在documentation进一步下跌:

[...]如果需要检查被调用的子分析器的名称,DEST关键字参数到add_subparsers()调用将工作

在您的例子取代:

subparsers = parser.add_subparsers(help='commands') 

有:

subparsers = parser.add_subparsers(help='commands', dest='command') 

现在,如果你运行:

print parser.parse_args(["all"]) 

你会得到

Namespace(command='all') 
+0

这似乎是正确的方式,因为它的作用就像任何其他参数上的'dest'参数(只有它默认为'None',而不是被拉从'--longopt'值)。使用'set_defaults'似乎不适用于此(但对其他事情有用) – dbr

+0

这是正确的答案!如果能够测试“命令”值,将会很好。 –

+0

顺便说一句,如果在同一个类中有函数可以执行的命令的名称:“getattr(self,args.command)()”按名称执行它! –

相关问题