从命令行获取参数,然后从文件获取参数,然后从默认值获取参数

时间:2013-02-13 12:59:35

标签: python argparse

我有一个根据一些参数运行的python程序。我们可以说,其中一个参数是C,默认值为3。因此,当我在没有任何参数的情况下运行它时,它会

$ python parsing.py
C=3

当我为初始数据加载文件时,它可以从该文件中获取一些参数值。例如,如果我的文件MakeC5表示程序应该与C=5一起运行,那么我会得到

$ python parsing.py --file=MakeC5
C=5

另一方面,如果我为C指定一个不同的值作为可选参数,则取该值,并优先于文件中的值。

$ python parsing.py --C=4
C=4

$ python parsing.py --file=MakeC5 --C=4
C=4

到此为止,我可以检查命令行中指定的值是否与默认值不同,否则从文件中取出一个值,与

一样
if parameters.C == parser.get_default('C'):
    parameters.C = load_file(parameters.file)["C"]

但是如果我在命令行中给出C的默认值,则此方法不起作用,如

$ python parsing.py --file=MakeC5 --C=3
C=3

我该如何处理这个案子?有没有一种方法不需要像

那样解析命令行两次
parameters = parser.parse_args()
parameters_from_file = load_file(parameters.file)
parser.set_defaults(**parameters_from_file)
parameters = parser.parse_args()

这对我来说不像“明显的pythonic方式”吗?这是准读取可以指定为参数的配置文件,因此我希望有一个好方法。

2 个答案:

答案 0 :(得分:5)

假设您使用argparse module,只需在添加参数时不设置默认参数。如果参数不存在,则属性将为None,您可以检查该属性,而不是两次解析参数:

parser.add_argument('--C'   , action='store', dest='C')
parser.add_argument('--file', action='store', dest='file')
# ...

args = parser.parse_args()
# ...

if args.C is None:
    # Argument `--C` not given on command line
    if args.file is not None:
        # Load the file, set `args.C` if the file contains the `C` option
        ...

if args.C is None:
    # `C` was neither specified on the command line argument given,
    # nor in the configuration file, set default value
    args.C = 3

print 'C =', args.C

答案 1 :(得分:1)

argsparsefromfile-prefix-chars,如果您能够忍受它的限制,它似乎会做您想要的一些。

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', default="ABC")
args = parser.parse_args()
print '#1', args.foo

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', default="ABC")
args = parser.parse_args(['--foo', 'BAR' ])
print '#2', args.foo

import argparse
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('--foo', default="ABC")
args = parser.parse_args(['--foo', 'BAR', '@myargs' ])
print '#3', args.foo

import argparse
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('--foo', default="ABC")
args = parser.parse_args(['@myargs', '--foo', 'BAR' ])
print '#4', args.foo

myargs

--foo
FISH

输出

#1 ABC
#2 BAR
#3 FISH
#4 BAR

注意@myargs在命令行中的位置如何影响foo的值,当它位于前面时,如果被--foo覆盖则重要,反之亦然。

这似乎可以做到你想要的地方:

  

default-value< config-file< cli-args

虽然它依赖于你记得以正确的顺序放置配置文件,但除非你拿args并重新排序它们以便它们首先在args中。

希望能有所思考。