fromfile_prefix_chars
的文档说明:
默认情况下,从文件中读取的参数每行只能读取一个(但请参见convert_arg_line_to_args()
),并被视为在命令行上引用原始文件参数的相同位置。
请注意,一个参数并不意味着一个选项加上它的所有参数,而是指一个命令行参数。当前整个行都被解释为单个参数。
换句话说,您的文件应该像这样:
--abool
--bunit
289
--cpath
/path/to/file.txt
或者,您可以重写convert_arg_line_to_args()
方法以其他方式解析文件。文档已经提供了一种实现,它解析空格分隔的参数而不是行分隔的参数:
def convert_arg_line_to_args(self, arg_line):
for arg in arg_line.split():
if not arg.strip():
continue
yield arg
我相信你可以通过子类化
ArgumentParser
并重新实现此方法,或者甚至在
ArgumentParser
实例上设置属性也可以起作用。
由于某种原因,
convert_arg_line_to_args
的默认实现无法正常工作:
$echo '--abool
--bunit
289
--cpath
/here/is/a/path
' > file.txt
$cat test_argparse.py
import argparse
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('--abool', action='store_true')
parser.add_argument('--bunit', type=int)
parser.add_argument('--cpath')
print(parser.parse_args(['@file.txt']))
$python test_argparse.py
usage: test_argparse.py [-h] [--abool] [--bunit BUNIT] [--cpath CPATH]
test_argparse.py: error: unrecognized arguments:
然而,如果您使用上述实现方法,它会起作用:
$cat test_argparse.py
import argparse
def convert_arg_line_to_args(arg_line):
for arg in arg_line.split():
if not arg.strip():
continue
yield arg.strip()
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument('--abool', action='store_true')
parser.add_argument('--bunit', type=int)
parser.add_argument('--cpath')
parser.convert_arg_line_to_args = convert_arg_line_to_args
print(parser.parse_args(['@file.txt']))
$python test_argparse.py
Namespace(abool=True, bunit=289, cpath='/here/is/a/path')
另一个解决方法是使用
--option=argument
语法:
--abool
--bunit=289
--cpath=/the/path/to/file.txt
然而,当选项有多个参数时,这种方法将无法使用。在这种情况下,您必须使用不同的convert_arg_line_to_args
实现。
尝试调试时,似乎会使用空字符串调用
convert_line_arg_to_args
,并将其添加到参数中,空字符串被视为参数(未定义)。
问题在于文件末尾有两个换行符。实际上,如果不在文件末尾添加双换行符,则可以正常运行:
$echo -n '--abool
--bunit
289
--cpath
/here/is/a/path
' > file.txt
$python test_argparse.py
Namespace(abool=True, bunit=289, cpath='/here/is/a/path')
(echo -n
不会在输出的末尾添加换行符)。