不能让argparse阅读引号字符串与它破折号?(Can't get argparse to

2019-08-31 22:36发布

有没有一种方法,使argparse承认两个引号之间的任何一个单一的参数? 它似乎总是看到破折号,并假设它是一个新的选择开始

我有这样的:

mainparser = argparse.ArgumentParser()
subparsers = mainparser.add_subparsers(dest='subcommand')
parser = subparsers.add_parser('queue')
parser.add_argument('-env', '--extraEnvVars', type=str,
                        help='String of extra arguments to be passed to model.')
...other arguments added to parser...

但是,当我运行:

python Application.py queue -env "-s WHATEVER -e COOL STUFF"

它给我:

Application.py queue: error: argument -env/--extraEnvVars: expected one argument

如果我离开关第一个破折号,它工作完全正常,但它是一种至关重要的是,我能在一个字符串传递与它破折号。 我试着\逃脱它,这会导致它成功,但增加了\的参数字符串有谁知道如何解决这个问题? 发生这种情况是否-s是解析器的参数。

编辑:我使用Python 2.7。

EDIT2:

python Application.py -env " -env"

工作完全正常,但

python Application.py -env "-env"

才不是。

EDIT3:看起来这实际上是就是BEING已经讨论了一个错误: http://www.gossamer-threads.com/lists/python/bugs/89529 , http://python.6.x6.nabble.com/issue9334- argparse -不-不接受选项回吐论点-开始-与破折号-回归-从- optp-td578790.html 。 它只有2.7,而不是在optparse。

EDIT4:当前打开的错误报告是: http://bugs.python.org/issue9334

Answer 1:

你可以开始与空间的说法python tst.py -e ' -e blah'作为一个非常简单的解决方法。 只要lstrip()选项把它恢复正常,如果你喜欢。

或者,如果第一个“子的说法”是不是也到原来的功能有效的参数,那么你应该不需要做任何事情。 也就是说,唯一的原因, python tst.py -e '-s hi -e blah'不工作是因为-s是一个有效的选项tst.py

此外, optparse模块,现在已经过时,工作没有任何问题。



Answer 2:

更新的答案:

你可以把一个等号,当你把它登录:

python Application.py -env="-env"

原来的答案:

我也有过烦恼做你正在尝试做的,但有一种变通方法建成argparse,这是parse_known_args方法。 这将让你没有通过与,你会使用它们的子进程的假设解析器定义的通过所有参数。 缺点是,你不会得到错误与错误参数报告,你将必须确保有你的选择,你的子进程的选项之间没有冲突。

另一种选择可能是迫使用户的使用,而不是减去加:

python Application.py -e "+s WHATEVER +e COOL STUFF"

传递给你的子进程之前,后处理 - 然后你改变“+”为“”。



Answer 3:

这个问题在深入讨论http://bugs.python.org/issue9334 。 大部分活动是在2011年我去年增加了一个补丁,但还有相当多的积压argparse补丁。

目前的问题是在这样一个字符串中的潜在的不确定性'--env' ,或"-s WHATEVER -e COOL STUFF"时,它遵循一个需要参数的选项。

optparse做一个简单的左到右解析。 第--env是一个选项标志,它有一个参数,所以它占用的未来,不管它是什么样子。 argparse ,在另一方面,遍历字符串的两倍。 首先,它对其进行分类为“O”或“A”(选项标志或参数)。 在第二个循环它消耗它们,使用re像模式匹配来处理可变nargs值。 在这种情况下,它看起来我们有OO ,两个标志,没有争吵。

当使用该解决方案argparse是确保一个参数字符串不会被迷惑一个选项标志。 已经在这里(和错误问题)显示可能包括:

--env="--env"  # clearly defines the argument.

--env " --env"  # other non - character
--env "--env "  # space after

--env "--env one two"  # but not '--env "-env one two"'

就其本身而言'--env'看起来像一个标志(报价甚至当,看到sys.argv ),但随后当其他字符串没有。 但"-env one two"有问题,因为它可以被解析为['-e','nv one two']一个`“-e”标记后跟一个字符串(或甚至更多选项)。

--nargs=argparse.PARSER也可用于强制argparse查看所有以下字符串作为参数。 但他们只在参数列表的工作进行到底。

有一个在issue9334提出的补丁添加args_default_to_positional=True模式。 在这种模式下,如果能清晰地定义的参数匹配它们解析器仅分类字符串作为选项标志。 因此,在“--env --one”“--one”将被归类为作为参数。 但是,在“--env --env”第二“--env”仍然会被归类为选项标志。


扩大对相关情况

使用argparse与同划线开头的参数值(“ - ”)

parser = argparse.ArgumentParser(prog="PROG")
parser.add_argument("-f", "--force", default=False, action="store_true")
parser.add_argument("-e", "--extra")
args = parser.parse_args()
print(args)

产生

1513:~/mypy$ python3 stack16174992.py --extra "--foo one"
Namespace(extra='--foo one', force=False)
1513:~/mypy$ python3 stack16174992.py --extra "-foo one"
usage: PROG [-h] [-f] [-e EXTRA]
PROG: error: argument -e/--extra: expected one argument
1513:~/mypy$ python3 stack16174992.py --extra "-bar one"
Namespace(extra='-bar one', force=False)
1514:~/mypy$ python3 stack16174992.py -fe one
Namespace(extra='one', force=True)

因为该“-foo一个”案失败-foo被解释为-f标志加上未指定临时演员。 这是相同的动作,其允许-fe被解释为['-f','-e']

如果我改变nargsREMAINDER (不PARSER ),之后一切-e被解释为是标志参数:

parser.add_argument("-e", "--extra", nargs=argparse.REMAINDER)

所有的情况下工作。 需要注意的值是一个列表。 并且不需要引号:

1518:~/mypy$ python3 stack16174992.py --extra "--foo one"
Namespace(extra=['--foo one'], force=False)
1519:~/mypy$ python3 stack16174992.py --extra "-foo one"
Namespace(extra=['-foo one'], force=False)
1519:~/mypy$ python3 stack16174992.py --extra "-bar one"
Namespace(extra=['-bar one'], force=False)
1519:~/mypy$ python3 stack16174992.py -fe one
Namespace(extra=['one'], force=True)
1520:~/mypy$ python3 stack16174992.py --extra --foo one
Namespace(extra=['--foo', 'one'], force=False)
1521:~/mypy$ python3 stack16174992.py --extra -foo one
Namespace(extra=['-foo', 'one'], force=False)

argparse.REMAINDER就像是“*”,不同的是它下面的一切,不论它看起来像一个标志或没有。 argparse.PARSER更像“+”,因为它需要一个positional的第一像的说法。 这是nargssubparsers用途。

这里使用的REMAINDER被记录在案, https://docs.python.org/3/library/argparse.html#nargs



Answer 4:

paser.add_argument("--argument_name", default=None, nargs=argparse.REMAINDER)

python_file.py --argument_name “--abc = 10 -a = 1 -b = 2 CDEF”

注:该参数值只有在双引号中传递,这并不单引号工作



文章来源: Can't get argparse to read quoted string with dashes in it?