sfe*_*ell 46 python command-line-interface argparse
有没有办法让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...
Run Code Online (Sandbox Code Playgroud)
但是当我跑步时:
python Application.py queue -env "-s WHATEVER -e COOL STUFF"
Run Code Online (Sandbox Code Playgroud)
它给了我:
Application.py queue: error: argument -env/--extraEnvVars: expected one argument
Run Code Online (Sandbox Code Playgroud)
如果我离开第一个破折号,它的工作完全正常,但是能够传入带有破折号的字符串是至关重要的.我已经尝试用\来转义它,这会导致它成功但是将\添加到参数字符串有没有人知道如何解决这个问题?无论-s是否是解析器中的参数,都会发生这种情况.
编辑:我正在使用Python 2.7.
EDIT2:
python Application.py -env " -env"
Run Code Online (Sandbox Code Playgroud)
工作得非常好,但是
python Application.py -env "-env"
Run Code Online (Sandbox Code Playgroud)
才不是.
EDIT3:看起来这实际上是就是BEING已经讨论了一个错误:http://www.gossamer-threads.com/lists/python/bugs/89529,http://python.6.x6.nabble.com/issue9334- argparse-does-not-accept-options-taking-arguments-beginning-with-dash-regression-from-optp-td578790.html.它仅在2.7中而不是在optparse中.
EDIT4:当前的开放式错误报告是:http://bugs.python.org/issue9334
Set*_*ton 49
更新的答案:
你可以在调用时给出一个等号:
python Application.py -env="-env"
Run Code Online (Sandbox Code Playgroud)
原始答案:
我也有麻烦做你想做的事情,但有一个变通方法构建到argparse,这是parse_known_args方法.这将允许您未定义的所有参数通过解析器,并假设您将它们用于子进程.缺点是您不会使用错误的参数进行错误报告,并且您必须确保选项和子进程选项之间没有冲突.
另一种选择可能是强制用户使用加号而不是减号:
python Application.py -e "+s WHATEVER +e COOL STUFF"
Run Code Online (Sandbox Code Playgroud)
然后在传递给子进程之前在后处理中将'+'更改为' - '.
hpa*_*ulj 17
这个问题在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"'
Run Code Online (Sandbox Code Playgroud)
它本身'--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)
Run Code Online (Sandbox Code Playgroud)
产生
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)
Run Code Online (Sandbox Code Playgroud)
"-foo one"案例失败,因为它-foo
被解释为-f
标志加上未指定的附加内容.这是允许-fe
被解释为的相同动作['-f','-e']
.
如果我更改nargs
to REMAINDER
(not PARSER
),则后面的所有内容都-e
被解释为该标志的参数:
parser.add_argument("-e", "--extra", nargs=argparse.REMAINDER)
Run Code Online (Sandbox Code Playgroud)
所有案例都有效.请注意,该值是一个列表.并且不需要报价:
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)
Run Code Online (Sandbox Code Playgroud)
argparse.REMAINDER
就像'*',除了它接下来的一切,无论它看起来像是旗帜. argparse.PARSER
更像是'+',因为它首先需要一个positional
类似的参数.它nargs
就是subparsers
用的.
这种用途REMAINDER
记录在案,https://docs.python.org/3/library/argparse.html#nargs
Wil*_*iam 13
您可以使用空格python tst.py -e ' -e blah'
作为一个非常简单的解决方法来启动参数.lstrip()
如果你愿意,只需将它恢复正常即可.
或者,如果第一个"子参数"也不是原始函数的有效参数,那么您根本不需要做任何事情.也就是说,唯一python tst.py -e '-s hi -e blah'
不起作用的原因是因为它-s
是一个有效的选项tst.py
.
此外,现已弃用的optparse模块也可以正常运行.
归档时间: |
|
查看次数: |
20886 次 |
最近记录: |