1. ホーム
  2. python

[解決済み] python argparse を使って複数のネストしたサブコマンドを解析するには?

2023-01-12 19:43:32

質問

このようなインターフェイスを持つコマンドライン・プログラムを実装しています。

cmd [GLOBAL_OPTIONS] {command [COMMAND_OPTS]} [{command [COMMAND_OPTS]} ...]

を経て argparse ドキュメント . 私は GLOBAL_OPTIONS をオプションの引数として実装することができます。 add_argumentargparse . そして、その {command [COMMAND_OPTS]} を使って サブコマンド .

ドキュメントを見ると、サブコマンドは1つしか持てないようです。しかし、ご覧のように、私は1つ以上のサブコマンドを実装する必要があります。このようなコマンドライン引数を解析するための最良の方法は argparse ?

どのように解決するのですか?

mgilson は、素敵な 回答 があります。しかし、sys.argvを自分で分割することの問題は、Argparseがユーザのために生成する素晴らしいヘルプメッセージをすべて失ってしまうということです。だから、私はこれを行うことを終了しました。

import argparse

## This function takes the 'extra' attribute from global namespace and re-parses it to create separate namespaces for all other chained commands.
def parse_extra (parser, namespace):
  namespaces = []
  extra = namespace.extra
  while extra:
    n = parser.parse_args(extra)
    extra = n.extra
    namespaces.append(n)

  return namespaces

argparser=argparse.ArgumentParser()
subparsers = argparser.add_subparsers(help='sub-command help', dest='subparser_name')

parser_a = subparsers.add_parser('command_a', help = "command_a help")
## Setup options for parser_a

## Add nargs="*" for zero or more other commands
argparser.add_argument('extra', nargs = "*", help = 'Other commands')

## Do similar stuff for other sub-parsers

さて、最初のパースの後、すべての連鎖したコマンドは extra . 私はそれが空でない間、すべての連鎖したコマンドを取得し、それらのために別々の名前空間を作成するためにそれを再パースします。そして、私はargparseが生成する、より良い使用状況文字列を取得します。