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

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

问题描述

在使用 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.

而且只是为了踢球,这是一个可怕的想法,可以告诉使用默认值和显式指定一个与默认值相同的值:

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天全站免登陆