我可以检查默认值还是用户提供的值? [英] Can I check if a value was supplied by the default or by the user?

查看:54
本文介绍了我可以检查默认值还是用户提供的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用 argparse 时,有没有一种方法可以判断一个字段是否具有值,是因为用户指定了该字段还是因为未指定该字段并获得了默认值?注意:我还要考虑用户明确指定默认值的情况.

Is there a way, when using argparse, to tell whether a field has a value because the user specified it or because it was not specified and got the default value? Note: I would also like to consider the case where the user explicitly specifies the default value.

我想使用 argparse 处理命令行参数,并且我想使用 formatter_class = argparse.ArgumentDefaultsHelpFormatter 显示字段的默认值未指定.另外,我想从配置文件中读取值.

I would like to use argparse to process command line arguments, and I would like to use formatter_class=argparse.ArgumentDefaultsHelpFormatter to display what the default value will be for fields that are not specified. In addition, I would like to read values from a config file.

如果用户在命令行上指定了一个值,我想确保使用该值(即使该值与默认值匹配,但已明确声明).如果用户未指定值,但在配置文件中找到一个值,则我想使用该值.如果用户未在命令行上指定一个,并且配置文件中没有值,那么我想使用上面用法说明中显示的默认值.

If the user specifies a value on the command line, I would like to make sure I use that value (even if that value matches the default, but was explicitly stated). If the user did not specify a value, but one is found in the config file, I would like to use that. If the user did not specify one on the command line, and there is not a value in the config file, then I would like to use the default value that was displayed in the usage statement above.

所以,我可能会像这样设置解析

So, I might set up the parse like

parser = parser = argparse.ArgumentParser( description="""Tool with many ways to get values""", formatter_class=argparse.ArgumentDefaultsHelpFormatter )
parser.add_argument( '-p', '--path', help="The path to a file to read", default="data.csv" )
parser.add_argument( '-c', '--conf', help="The config file to use", default="config.txt" )

也许还有许多其他参数.

and perhaps there are many other parameters.

现在,我还要读取一个配置文件,其中可能包含一个值

Now, I would like to also read a config file, which may include a value

data_path = data2.csv

因此,如果用户在命令行上指定 -p ,我想读取该文件;如果他们没有,而我使用该配置文件,我想阅读 data2.csv ;如果我使用未定义 data_path 的配置文件,并且未指定 -p ,则我想使用默认的 data.csv .

So if the user specifies a -p on the command line, I would like to read that file; if they do not and I use that config file, I would like to read data2.csv; and if I use a config file that does not define data_path and they do not specify -p, I would like to use the default data.csv.

对我来说,最主要的情况是,如果用户指定 -p data.csv ,则它将具有默认值,但应优先于配置文件.

The main complicating case for me would be if the user specifies -p data.csv then it will have the value of the default value, but should take precedence over the config file.

argparse 或其他类似工具是否可以告诉参数是通过默认设置还是由用户显式设置?

Does argparse or another similar tool have a way to tell if the parameter was set by falling through to the default or was explicitly set by the user?

推荐答案

如果只是使事情复杂,请不要指定默认值:

Don't specify a default value if it's just complicating things:

parser.add_argument('-p', '--path', 
                    help="The path to a file to read")

然后在代码中:

if args.path:
    # user specify a value for path
    # using -p
    pass
elif cfg.path:
    # user provided a path in the configuration value
    args.path = cfg.path
else:
    # no value was specified, use some sort of default value
    args.path = DEFAULT_PATH

或者更紧凑:

args.path = next(val for val in 
                 [args.path, cfg.path, DEFAULT_PATH]
                 if val is not None)

这假设如果在配置文件中未指定路径,则 cfg.path 将为 None .因此,如果 cfg 实际上是字典,那么 cfg.get('path')会做正确的事情.

This assumes that cfg.path will be None if no path was specified in the config file. So if cfg is actually a dictionary, cfg.get('path') would do the right thing.

这只是个好主意,这是一个可怕的主意,可以告诉使用默认值和显式指定a之间的区别值与默认值相同:

And just for kicks, here's a terrible idea that can tell the difference between using a default value and explicit specifying a value that is the same as the default:

import argparse

class Default(object):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return str(self.value)

DEFAULT_PATH = Default('/some/path')

def parse_args():
    p = argparse.ArgumentParser()
    p.add_argument('--path', '-p',
                   default=DEFAULT_PATH)
    return p.parse_args()

def main():
    args = parse_args()

    if args.path is DEFAULT_PATH:
        print 'USING DEFAULT'
    else:
        print 'USING EXPLICIT'

    print args.path

if __name__ == '__main__':
    main()

请注意,我实际上并不认为这是个好主意.

Note that I don't actually think this is a good idea.

这篇关于我可以检查默认值还是用户提供的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆