我有以下代码,用于从文件中读取参数并使用argparse处理它们,但我得到了一个错误,为什么会这样?
import argparse
from ConfigParser import ConfigParser
import shlex
parser = argparse.ArgumentParser(description='Short sample app',
fromfile_prefix_chars='@')
parser.add_argument('--abool', action="store_true", default=False)
parser.add_argument('--bunit', action="store", dest="bunit",type=int)
parser.add_argument('--cpath', action="store", dest="c", type=str)
print parser.parse_args(['@argparse_fromfile_prefix_chars.txt']) #name of the file is argparse_fromfile_prefix_chars.txt错误:
usage: -c [-h] [--abool] [--bunit BUNIT] [--cpath C]
-c: error: unrecognized arguments: --bunit 289 --cpath /path/to/file.txt
To exit: use 'exit', 'quit', or Ctrl-D.argparse_fromfile_prefix_chars.txt文件的内容
--abool
--bunit 289
--cpath /path/to/file.txt发布于 2014-08-28 04:57:27
argparse期望来自文件的参数是每行一个。这意味着整行都是一个被引用的参数。因此,您当前的args文件被解释为
python a.py '--abool' '--bunit 289' '--cpath /path/to/file.txt'这会导致错误。相反,您的args文件应如下所示
--abool
--bunit
289
--cpath
/path/to/file.txt发布于 2014-08-28 04:58:39
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):
# consider using shlex.split() instead of arg_line.split()
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不会在输出末尾添加换行符)。
https://stackoverflow.com/questions/25536581
复制相似问题