5

コマンドラインを解析するために pythons(2.7.2) argparse (1.1) を使用しています。サブパーサーを作成し、サブパーサーコマンドを複数回入力できるようにしたいのです。このような:

./script.py version 1 --file 1 2 3 version 3 --file 4 5 6

そのようなものを作成することは可能ですか?結果の名前空間でそのような引数を使用してスクリプトを実行しようとすると、次のようになるためです。

Namespace(file=['4', '5', '6'], n=[1])

n バージョン番号です。そのため、ファイル リストとバージョンの両方ではなく、最初のバージョン番号と 2 番目のファイル リストを取得します。

4

1 に答える 1

5

メインのパーサーにとって、サブパーサーの引数は選択肢を取る定位置です。ただし、残りの引数文字列もすべてサブパーサーに割り当てます。

あなたの文字列は次のように解析されると思います:

./script.py version 1 --file 1 2 3 version 3 --file 4 5 6

versionサブパーサー名として受け入れられます。 1位置引数 の値として受け入れられますn。(サブパーサーの)。--fileオプションの引数として (サブパーサーによって) 受け入れられます。2 番目の呼び出しの値は、最初の呼び出しの値を上書きします。私は持っていると推測し--fileていnargs='*'ます。その場合、最初のものは['1','2','3','version','3']名前空間に書き込み、2 番目のものはそれを で上書きし['4','5','6']ます。の場合nargs=3、サブパーサーが 2 番目の でチョークすることを期待しversionます。これは、未知の位置として認識されます。

したがって、基本的なポイントは、「バージョン」サブパーサーが引数リストを取得すると、可能な限りすべてを解析するまで手放さないということです。この場合、両方の--file出現を解析します。処理できないものはすべて「UNKNOWNS」としてメイン パーサーに返され、通常はエラーが発生します。


繰り返されるオプションから値が必要な場合は、追加アクションを使用します

parser.add_argument('--foo',action='append', nargs=3)

import argparse
parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='version')
spp = sp.add_parser('version')
spp.add_argument('n',nargs='*',type=int)
spp.add_argument('--file',nargs=3,action='append')
str = 'version 1 --file 1 2 3 version 3 --file 4 5 6'
print(parser.parse_known_args(str.split()))

生産する

(Namespace(file=[['1', '2', '3'], ['4', '5', '6']], n=[1], version='version'), ['version', '3'])

サブパーサーへの呼び出しは 1 回だけversionですが、すべてのデータが存在します。


別のアプローチは、サブパーサーをネストすることです

parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='sub')
spp = sp.add_parser('version')
spp.add_argument('n',nargs=1,type=int)
spp.add_argument('--file',nargs=3)

sp = spp.add_subparsers(dest='sub1')
spp = sp.add_parser('version')
spp.add_argument('n1',nargs=1,type=int)
spp.add_argument('--file',dest='file1',nargs=3)

str = 'version 1 --file 1 2 3 version 3 --file 4 5 6'
print(parser.parse_args(str.split()))

値の上書きを避けるために、「dest」を変更する必要があることに注意してください。これにより、

Namespace(file=['1', '2', '3'], file1=['4', '5', '6'], n=[1], n1=[3], sub='version', sub1='version')
于 2013-10-01T15:55:48.270 に答える