使用互斥的组参数作为函数的标志

时间:2016-03-13 06:12:18

标签: python-2.7 argparse

我编写了以下程序,其目标是根据互斥参数列出特定类型的项目。

def run():
    parser = argparse.ArgumentParser(description='List Items')
    group = parser.add_mutually_exclusive_group(required=True)
    sub_parsers = parser.add_subparsers(help='list commands')
    listItems_parser = sub_parsers.add_parser('listitem', help='List items in the directory')
    listItems_parser.add_argument('-s','--source_dir', help='Source Directory',required = True)
    listItems_parser = group.add_argument('-t','--tonic',help='List Tonic', action ='store_true')
    listItems_parser = group.add_argument('-c','--capsule',help='List Capsule', action ='store_true')
    listItems_parser.set_defaults(func=run_iList_commands)

    args = parser.parse_args()
    args.func(args)

但是当我运行该程序时,我收到以下错误:

AttributeError: '_StoreTrueAction' object has no attribute 'set_defaults'

请帮我理解这个问题。

1 个答案:

答案 0 :(得分:1)

此语句创建一个分配给listItemss_parser

的解析器
listItems_parser = sub_parsers.add_parser('listitem', help='List items in the directory')

这会在该解析器中创建一个参数(Action)。

listItems_parser.add_argument('-s','--source_dir', help='Source Directory',required = True)

这也会创建一个参数Action对象,但是在group(之前被定义为主parser的一部分。

由于某些未知原因,您将此对象分配给您之前用于子分析程序的相同变量名称。为什么?您是否尝试将此参数添加到该子分析器?

listItems_parser = group.add_argument('-t','--tonic',help='List Tonic', action ='store_true')

相同类型的参数赋值:

listItems_parser = group.add_argument('-c','--capsule',help='List Capsule', action ='store_true')

请记住,listItems_parser现在是Action,而不是parser - 因此错误。

listItems_parser.set_defaults(func=run_iList_commands)

我怀疑你想做点什么:

group = listItems_parser.add_multually....
group.add_argument(...)
group.add_argument(...)

换句话说,将group定义为subparser。

listItems_parser.set_defaults(func=run_iList_commands)
args = parser.parse_args(['listitem',...])

当'listitem'在命令行中时,运行listItems_parser,并为它定义的所有参数设置默认值和值。由于此set_defaults命令,args命名空间将包含func项。 (我认为这在文档中有说明)。

换句话说,args看起来像(打印):

Namespace(func=run_iList_commands, source_dir=..., tonic=..., capsule=....)

所以这一行:

args.func(args)

最终调用run_iList_commands函数,并获得此命名空间作为参数。在这个功能里面它可以做到:

args.source.dir...
if args.tonic:
   etc

我强烈建议在交互式会话中运行此操作或更简单的操作,并打印各种值。这样一个会话中发生的事情比解释它们更容易。

相关问题