argparseにsub_parsersにわずかな制限があるような気がします。たとえば、さまざまなレベルにまたがる可能性のある同様のオプションを持つツールスイートがあります。このような状況はまれであるかもしれませんが、プラグイン可能な/モジュラーコードを作成している場合、それが起こる可能性があります。
次の例があります。それはこじつけと、それは非常に遅くなるためだけでなく、現時点では説明しませんが、ここではそれが行く:あなたが見ることができるように
Usage: tool [-y] {a, b}
a [-x] {create, delete}
create [-x]
delete [-y]
b [-y] {push, pull}
push [-x]
pull [-x]
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('-x', action = 'store_true')
parser.add_argument('-y', action = 'store_true')
subparsers = parser.add_subparsers(dest = 'command')
parser_a = subparsers.add_parser('a')
parser_a.add_argument('-x', action = 'store_true')
subparsers_a = parser_a.add_subparsers(dest = 'sub_command')
parser_a_create = subparsers_a.add_parser('create')
parser_a_create.add_argument('-x', action = 'store_true')
parser_a_delete = subparsers_a.add_parser('delete')
parser_a_delete.add_argument('-y', action = 'store_true')
parser_b = subparsers.add_parser('b')
parser_b.add_argument('-y', action = 'store_true')
subparsers_b = parser_b.add_subparsers(dest = 'sub_command')
parser_b_create = subparsers_b.add_parser('push')
parser_b_create.add_argument('-x', action = 'store_true')
parser_b_delete = subparsers_b.add_parser('pull')
parser_b_delete.add_argument('-y', action = 'store_true')
print parser.parse_args(['-x', 'a', 'create'])
print parser.parse_args(['a', 'create', '-x'])
print parser.parse_args(['b', '-y', 'pull', '-y'])
print parser.parse_args(['-x', 'b', '-y', 'push', '-x'])
出力
Namespace(command='a', sub_command='create', x=True, y=False)
Namespace(command='a', sub_command='create', x=True, y=False)
Namespace(command='b', sub_command='pull', x=False, y=True)
Namespace(command='b', sub_command='push', x=True, y=True)
、それがするのは難しいです各引数が連鎖に沿ってどこに設定されているかを区別します。 これを解決するには、各変数の名前を変更します。たとえば、 'dest'を 'x'、 'a_x'、 'a_create_x'、 'b_push_x'などに設定することはできますが、それは痛みを伴い分離しにくいでしょう。
代わりに、ArgumentParserをサブコマンドに達すると停止し、残りの引数を別の独立したパーサーに渡すことで別のオブジェクトを生成することもできます。 'parse_known_args()'を使用し、各サブコマンドに引数を定義しないことで、これを達成できます。しかし、以前からの解析されていない引数が存在し、プログラムを混乱させる可能性があるため、それはうまくいかないでしょう。
私はやや安いですが、便利な回避策は、次の引数をargparseにリストの文字列として解釈させることです。接頭辞をヌルターミネーター '\ 0'(または他の「使用しにくい」文字)に設定することでこれを行うことができます。接頭辞が空の場合、コードは少なくともPython 2.7ではエラーをスローします。 3。
例:
parser = ArgumentParser()
parser.add_argument('-x', action = 'store_true')
parser.add_argument('-y', action = 'store_true')
subparsers = parser.add_subparsers(dest = 'command')
parser_a = subparsers.add_parser('a' prefix_chars = '\0')
parser_a.add_argument('args', type = str, nargs = '*')
print parser.parse_args(['-xy', 'a', '-y', '12'])
出力:それは二-y
オプションを消費しないことを
Namespace(args=['-y', '12'], command='a', x=True, y=True)
注意。 結果 'args'を別のArgumentParserに渡すことができます。
欠点:
- ヘルプがうまく処理されない場合があります。
- エラーが発生するのは追跡が難しく、エラーメッセージが適切に連鎖されていることを確認するために何らかの努力が必要な場合があります。
- 複数のArgumentParserに関連付けられたオーバーヘッドが少し増加します。
これ以上入力がない場合は、教えてください。
私が働いている会社はそうargparseを使用してV2.6ベースラインは、それが外部ライブラリとして含まれており、必要な場合にのみロードされなければならないという点で問題がある持っています。不可能から遠い、理想的ではない。 cmdlnライブラリに関しては、私が再作成したくないベースライン機能の素敵なビットを私に与えます。それは私が何か他のものを使うことに反対していると言った。 – tima