我有一个python程序,它根据一些参数运行。假设其中一个参数是默认值为3
的C
。所以当我在没有任何争论的情况下运行它时,它会进行
$ 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()
在我看来,这不是"明显的蟒蛇式的方式"?这是准读取一个可以指定为参数的配置文件,所以我希望有一个好方法。
假设使用argparse
模块,添加参数时只需不设置默认参数即可。如果参数不存在,那么属性将是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
在argsparse中有fromfile前缀字符,如果你能接受它的限制,它似乎可以做一些你想做的事情。
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
覆盖,则会对其进行赋值,反之亦然。
这似乎可以做你想做的事情:
默认值<配置文件<cli args
尽管它依赖于你记住按照正确的顺序放置配置文件,当然,除非你接受参数并重新排序,使它们位于参数中的第一位。
希望能引起思考。