我可以检查默认值还是用户提供的值?

时间:2015-06-06 01:56:09

标签: python argparse

使用argparse时,是否有办法判断某个字段是否有值,因为用户指定了该字段,或者是否未指定该字段并获得默认值? 注意:我还想考虑用户明确指定默认值的情况。

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

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

所以,我可能会像

那样设置解析
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" )

也许还有很多其他参数。

现在,我还想阅读配置文件,其中可能包含值

data_path = data2.csv

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

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

argparse或其他类似工具是否有办法判断参数是通过降至默认值还是由用户明确设置来设置的?

1 个答案:

答案 0 :(得分:3)

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

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.pathNone。因此,如果cfg实际上是字典,cfg.get('path')会做正确的事。

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

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()

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