如何让argparse在位置参数后使用选项从文件中读取参数

How to get argparse to read arguments from a file with an option after positional arguments

我希望能够将命令行参数放入文件中,然后将它们传递给 python 程序,使用 argparse,使用选项而不是前缀字符,例如: $ 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,该文件旨在仅处理文件的内容。我会在全球范围内定义它。

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。所有其他解析变量都是调用代码的本地变量。