我有一个根据一些参数运行的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方式”吗?这是准读取可以指定为参数的配置文件,因此我希望有一个好方法。
答案 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)
在argsparse内fromfile-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中。
希望能有所思考。