子解析器的Argparse set_defaults超越了Python 2.7.6?

时间:2015-10-03 03:15:19

标签: python

我有一个使用argparse的应用程序,它被最新版本的Python打破。我不再能够改变子命令的默认值。

我的应用程序有各种模块和可选的GUI。 GUI通过子命令调用模块,并且有一个ini文件可以改变参数默认值。

GUI创建了解析器和子解析器,传递GUI用户设置的参数。 ini文件中的选项可能会覆盖子解析器中的默认值。

这适用于2.7.6,但由于argparse的明显变化而被后来的版本打破。

import argparse

# create the top-level parser
parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('--foo', action='store_true', dest='_foo')
subparsers = parser.add_subparsers(help='sub-command help')

# create the parser for the "a" command
parser_a = subparsers.add_parser('a', help='a help')
parser_a.add_argument('--bar', type=int, default=0, dest='_bar')

#use ini file to alter default 
d_ini = {'_bar': '1'}
parser.set_defaults(**d_ini)

# parse some argument lists
print parser.parse_args(['a'])

在python 2.7.6中按预期打印:

  
    

命名空间(_bar = 1,_foo = False)

  

但在后来的版本中,例如。 2.7.10打印

  
    

命名空间(_bar = 0,_foo = False)

  

我是否错误地使用了argparse,因为如果这是一个python错误,它现在已经持续了几个版本?

在添加子解析器默认值之前,是否需要处理ini文件?这将比我目前的方法更麻烦,因为它需要为每个参数单独完成,并且有很多。 ArgumentParser.set_defaults的python文档明确指出"在使用多个解析器时,解析器级默认值特别有用,因此如果此工具受到危害,则会令人惊讶。

1 个答案:

答案 0 :(得分:1)

在这种情况下,必须将解析器默认值应用于感兴趣的子解析器。也就是说,在上面的代码中,您应该:

# set defaults on parser_a
parser_a.set_defaults(**d_ini)

parser上设置默认值不会在子解析器上设置默认值。相反,它设置顶级(全局)参数的默认值。为什么?通过这种方式,程序可以选择--bar,对于多个子命令abc也可以选择--bar具有不同的默认值。

2.7.6中的前一种行为(也出现在3.3中)应被视为一种错误。