首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Argparse中的异常

Argparse中的异常
EN

Stack Overflow用户
提问于 2014-08-28 04:43:04
回答 2查看 501关注 0票数 3

我有以下代码,用于从文件中读取参数并使用argparse处理它们,但我得到了一个错误,为什么会这样?

代码语言:javascript
复制
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

错误:

代码语言:javascript
复制
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文件的内容

代码语言:javascript
复制
--abool
--bunit 289
--cpath /path/to/file.txt
EN

回答 2

Stack Overflow用户

发布于 2014-08-28 04:57:27

argparse期望来自文件的参数是每行一个。这意味着整行都是一个被引用的参数。因此,您当前的args文件被解释为

代码语言:javascript
复制
python a.py '--abool' '--bunit 289' '--cpath /path/to/file.txt'

这会导致错误。相反,您的args文件应如下所示

代码语言:javascript
复制
--abool
--bunit
289
--cpath
/path/to/file.txt
票数 1
EN

Stack Overflow用户

发布于 2014-08-28 04:58:39

fromfile_prefix_chars的文档说明:

默认情况下,从文件读取的

参数必须是每行一个(但另请参见convert_arg_line_to_args()),并被视为与命令行上的原始文件引用参数位于同一位置。

请注意,一个参数不是是指一个选项后面跟着它的所有参数。它表示命令行参数。目前,整行代码被解释为好像它们是一个单独的参数。

换句话说,您的文件应该如下所示:

代码语言:javascript
复制
--abool
--bunit
289
--cpath
/path/to/file.txt

或者,您可以覆盖convert_arg_line_to_args()方法,以另一种方式解析文件。文档已经提供了一个解析空格分隔参数而不是行分隔参数的实现:

代码语言:javascript
复制
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的默认实现不能正常工作:

代码语言:javascript
复制
$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:

但是,如果您使用上面的实现,它可以工作:

代码语言:javascript
复制
$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语法:

代码语言:javascript
复制
--abool
--bunit=289
--cpath=/the/path/to/file.txt

但是,当一个选项有多个参数时,这将不起作用。在这种情况下,您必须使用不同的convert_arg_line_to_args实现。

在尝试调试时,似乎使用添加到参数中的空字符串调用了convert_line_arg_to_args,并且该空字符串被认为是一个参数(未定义)。

问题是文件末尾有两个换行符。实际上,如果您创建的文件末尾没有这个双换行符,则可以正常工作:

代码语言:javascript
复制
$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不会在输出末尾添加换行符)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25536581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档