我有一个使用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的python文档。set_defaults明确地声明"在使用多个解析器时,解析器级别的默认值可能特别有用",所以如果这个功能被破坏了,那就令人惊讶了。
在这种情况下,必须将解析器默认值应用于感兴趣的子解析器。也就是说,在上面的代码中,您应该有:
# set defaults on parser_a
parser_a.set_defaults(**d_ini)
在parser
上设置默认值不会在子解析器上设置默认值。相反,它为顶级(全局)参数设置默认值。为什么?这样,程序就有可能采用一个选项--bar
,并且对于多个子命令a
, b
, c
也都采用不同默认值的选项--bar
。
前一种行为,在2.7.6中,也出现在3.3中,应该被认为是一个bug。