如何确定是否在命令行中实际指定了argparse参数?

时间:2015-08-17 18:05:44

标签: python argparse

我使用arparse使用命令行中指定的值更新配置dict。因为我只想更新配置中的值,在命令行中明确提到了值。

因此,我尝试通过检查每个动作来识别未指定的参数getattr(args, action.dest) == action.default或转换类型的等式arg。然后我更新dict中我的所有值,这是错误的。

但是这当然失败了,如果我在命令行中明确指定一个与我的默认参数相同的参数。是否有可能用argparser识别这些明确提到的论点,或者我有 在sys.argv中手动识别它们?

谢谢!

修改

让我的意图更清晰。我有一个如下的论点:

parser.add_argument('--test', default='meaningful_default')

之类的配置

config = { 'test' : 'nondefault_val'}

现在我想只使用明确指定的参数更新配置。将args属性与默认值进行比较只要我没有指定prog.py --test meaningful_default之类的东西来再次更新我的配置,其值恰好也是默认值

4 个答案:

答案 0 :(得分:4)

parser在解析时(在seen_actions方法中)维护_parse_known_args设置对象。在解析结束时,它会根据所需的参数(具有required=True的参数)检查此集合,并可能发出错误。变体也用于互斥组。

但是这个变量在该函数之外是不可用的。如此短暂的某种“钩子”允许您在parse_args动作中应用自己的测试,您最好的选择是测试默认值。或者你可以查看sys.argv[1:]

默认defaultNone。这很好用于此目的,因为您的用户无法提供此值。也就是说,没有字符串可以转换为None(至少在任何普通的type方法中都没有。)

parser.add_argument('--foo') # default=None
...
if args.foo is None:
    # clearly foo has not been specified.
    args.foo = 'the real default'
else:
    # foo was specified
    pass

答案 1 :(得分:1)

您可以使用自定义操作来判断arg值是默认值还是在命令行上设置的值:

import argparse

class FooAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values)
        setattr(namespace, self.dest+'_nondefault', True)

parser = argparse.ArgumentParser()
parser.add_argument('--test0', default='meaningful_default', action=FooAction)
parser.add_argument('--test1', default='meaningful_default', action=FooAction)

args = parser.parse_args('--test0 2'.split())

if hasattr(args, 'test0_nondefault'):
    print('argument test0 set on command line')
else:
    print('default value of test0 is used')

if hasattr(args, 'test1_nondefault'):
    print('argument test1 set on command line')
else:
    print('default value of test1 is used')

答案 2 :(得分:0)

如果您更喜欢使用argparse并且能够指定默认值,那么使用两个解析器就有一个简单的解决方案。

予。定义主解析器并使用正确的默认值解析所有参数:

parser = argparse.ArgumentParser()
parser.add_argument('--test1', default='meaningful_default1')
parser.add_argument('--test2', default='meaningful_default2')
...
args, unparsed = parser.parse_known_args()

II。使用argument_default=argparse.SUPPRESS定义辅助解析器以排除未指定的参数。添加主解析器中的所有参数,但没有任何默认值:

aux_parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
for arg in vars(args): aux_parser.add_argument('--'+arg)
cli_args, _ = aux_parser.parse_known_args()

这不是一个非常优雅的解决方案,但与argparse及其所有好处相得益彰。

答案 3 :(得分:0)

您可以使用“ const”和“ default”的组合来模拟所需的内容。在这种情况下,“ nargs”必须为'?'。例如:

args_group.add_argument('--abc',
                         metavar='',
                         nargs='?',
                         action='store',
                         const='github.com',
                         default='',
                         help='blabla [ default: %(const)s ]')

然后,abc的值将在不同的命令行参数下如下所示。

abc不在命令行中

  

abc =

--abc

  

abc = github.com

--abc stackoverflow.com

  

abc = stackoverflow.com

因此,您将知道abc在空白时没有出现在命令行中,例如:

if not args.abc:
    # to something