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 。元のパーサーを親として子サブパーサーに渡すことができると読みましたが、これでは問題は解決しません。add_help=False と conflict_handler='resolve' を最初のパーサー宣言に追加してみました。誰かがこれについて正しい方向に私を向けることができますか?

ありがとう、スコット

4

2 に答える 2

1

を解析するとき./test.py --optional foo bar、argparse はオプションの文字列 (- で始まる) とそれに続く 2 つの引数文字列 (- なし) を認識します。

したがって、処理から始まります--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

subparser2番目の例のように食べ尽くされて使用されOPTIONALています。argparseがサブパーサーがサブパーサーであることを事前に理解していないことを除いて、理由はわかりません。

これはあなたが説明していることに私が作ることができる最も近いものです:

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 に答える