3
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    '--optional',
    default=None,
    const='some-const',
    nargs='?',
    help='optional')

subparsers = parser.add_subparsers()

subparser = subparsers.add_parser('subparser')

subparser.add_argument(
    'positional',
    help='positional')

args = parser.parse_args()

print args

./test.py --optional opt subparser positional
Namespace(optional='opt', positional='positional')  <-- works as expected

./test.py --optional subparser positional
usage: test.py [-h] [--optional [OPTIONAL]] {subparser} ...
test.py: error: invalid choice: 'positional' (choose from 'subparser')  <-- throws an error
 Namespace(optional='some-const', positional='positional')  <-- would expect to see this

以上是我演示这个问题的最简单的测试代码。我想有一个使用 nargs='?' 的可选参数 和 const子解析器中我的位置 arg 之前。我读过我可以将原始解析器作为父子解析器传递给子子解析器,但这并不能解决问题。当我尝试这样做时,我尝试将 add_help=False 和 conflict_handler='resolve' 添加到初始解析器声明中。谁能指出我正确的方向?

谢谢,斯科特

4

2 回答 2

1

解析时./test.py --optional foo bar,argparse 看到一个可选字符串(以 -- 开头)后跟两个参数字符串(没有 --)

所以它从处理开始--optional。它的 nargs 是一个“贪婪的?”,所以它消耗了foo参数,产生:

Namespace('optional'='foo')

这留下bar作为子命令参数使用。

它不检查是否foo是有效的子命令参数。

同样的道理也适用于./test.py --optional subparser positional

于 2013-08-15T02:57:17.770 回答
0

这会引发错误:

.test.py --optional

因为subparser不是可选的:

usage: subparser.py [-h] [--optional [OPTIONAL]] {subparser} ...
test.py: error: too few arguments

subparserOPTIONAL就像你的第二个例子一样被吃掉和使用。我不明白为什么,除了 argparse 没有提前弄清楚 subparser 是 subparser 之外。

这是我能做的最接近你所描述的事情:

import argparse

parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument(
    '--optional',
    nargs='?',
    default=None,
    const='some-const',
    help='optional')

sub_parser = argparse.ArgumentParser(parents=[parent_parser])
sub_parser.add_argument('--subparser', required=True)

args = sub_parser.parse_args()

print args

我想你已经发现了一个错误。

于 2013-01-02T06:15:16.090 回答