【发布时间】:2017-02-24 21:55:20
【问题描述】:
我希望能够将命令行参数放入文件中,然后使用选项而不是前缀字符将它们传递给带有 argparse 的 python 程序,例如:
$ python myprogram.py 1 2 --foo 1 -A somefile.txt --bar 2
这与this question 几乎相同,只是我需要在开始时有一些位置参数;当该解决方案调用parse_args 时,如果文件中没有位置参数,它将失败。
【问题讨论】:
我希望能够将命令行参数放入文件中,然后使用选项而不是前缀字符将它们传递给带有 argparse 的 python 程序,例如:
$ python myprogram.py 1 2 --foo 1 -A somefile.txt --bar 2
这与this question 几乎相同,只是我需要在开始时有一些位置参数;当该解决方案调用parse_args 时,如果文件中没有位置参数,它将失败。
【问题讨论】:
如果somefile.txt 包含
one
two
three
然后
$ python myprogram.py 1 2 --foo 1 @somefile.txt --bar 2
使用prefix char实际上与
$ python myprogram.py 1 2 --foo 1 one two three --bar 2
也就是说,在解析的开始,@文件被读取,其内容被拼接到argv列表中。从那里开始正常解析。
我在另一个 SO 问题中建议的一件事是在解析之前自己实现拼接。
您所指的答案使用custom 操作;在通常的Action 只是将value 放入namespace 的地方,此操作会读取并解析文件:
parser.parse_args(f.read().split(), namespace)
一个变体解析成一个新的namespace,并选择性地将值复制到主namespace。
显然你的问题是你的解析器有一些必需的参数,如果文件不包含这些参数,parse_args 会引发错误。这并不奇怪。
一种解决方案是为此文件使用不同的parser,该parser 旨在仅处理文件的内容。我会在全局范围内定义它。
alt_parser.parse_args(f.read().split(), namespace)
换句话说,您不必使用作为参数传入的parser。
对此的一种变体是将文件名放在命名空间中,并在第一次解析后处理它:
args = parser.parse_args()
if args.A:
argv = open(args.A).read().split()
args1 = alt_parser.parse_args(argv)
但是你可能会问,我们不能知道哪些参数已经被解析,并在处理-A 时考虑到这一点吗? parser 不是状态机;解析不会改变它的任何属性。到目前为止,唯一反映解析的变量是namespace。所有其他解析变量都是调用代码的本地变量。
【讨论】:
@ 做了正确的事情,但我正在复制另一个程序的行为。这是有道理的;现在的诀窍是使用相同的参数制作第二个解析器,但没有必需的位置参数。
parents。然后您只需将positionals 添加到child。