12

オプションのパラメータを使用して、引数の後に位置引数を指定できるかどうか疑問に思いました。理想的には、コマンドラインに入力された最後の引数は常に「testname」に適用されます。

import argparse
parser = argparse.ArgumentParser(description='TAF')
parser.add_argument('-r','--release',nargs='?',dest='release',default='trunk')
parser.add_argument('testname',nargs='+')
args = parser.parse_args()

これらの呼び出しの両方でsmoketestをtestnameに適用したいのですが、2番目の呼び出しでエラーが発生します。

>> python TAF.py -r 1.0 smoketest
>> python TAF.py -r smoketest
TAF.py: error: too few arguments

位置引数を前に移動すると、オプションのパラメーターが正しく動作することを理解していますが、これは私が探している形式ではありません。選択フラグは魅力的な選択肢のように見えますが、一致しないアイテムを無視する代わりにエラーをスローします。

編集:私はこれを回避するためのハッキーな方法を見つけました。誰かがより良い解決策を持っているなら、私はそれをいただければ幸いです。

import argparse
parser = argparse.ArgumentParser(description='TAF')
parser.add_argument('-r','--release',nargs='?',dest='release',default='trunk')
parser.add_argument('testname',nargs=argparse.REMAINDER)
args = parser.parse_args()

if not args.testname:
    args.testname = args.release
    args.release = ''
4

1 に答える 1

4

ドキュメントに記載されているように:

'?'. 1 つの引数は、可能であればコマンド ラインから消費され、単一のアイテムとして生成されます。コマンドライン引数が存在しない場合、デフォルトの値が生成されます。オプションの引数の場合、追加のケースがあることに注意してください。オプション文字列は存在しますが、コマンドライン引数が続きません。この場合、const からの値が生成されます。

したがって、あなたが望む動作は を使用して取得することはできません'?'argparse.Actionおそらく、以前の結果を使用して干渉するハックを書くことができます.(1)

より良い解決策は、そのオプションの機能を分割することだと思います。引数が必要なオプションにして(ただし、オプション自体はオプションです)、リリースを に設定する引数なしのオプションを追加します'trunk'。このようにして、ハッキングなしで同じ結果を得ることができます。また、インターフェースがよりシンプルになったと思います。

あなたの例では:

python TAF.py -r smoketest

smoketestが への引数として解釈されることは明らかです-r。少なくとも UNIX の規則に従ってください。保持したい場合nargs='?'、ユーザーは次を使用する必要があり--ます。

$ python TAF.py -r -- sometest
Namespace(release=None, testname=['sometest'])   #parsed result

(1)これを行う方法のアイデア:オプションに引数があるかどうかを確認してください。有効なテスト名であるかどうかのチェックが 1 つある場合。その場合は手で入れてデフォルト値にtestname設定してください。releaseまた、このことが起こったことを知らせる「フラグ」を設定する必要があります。

ここで、解析sys.argvする前にリダイレクトする必要がありますsys.stderr。解析を実行するときは、 catchSystemExitをチェックしてstderr、エラーが「引数が少なすぎる」かどうかを確認し、フラグが設定されているかどうかを確認します。設定されている場合は、エラーを無視して実行を続行します。そうでない場合は、元stderrのエラー メッセージに再出力して終了する必要があります。 .

このアプローチは堅牢に見えず、おそらくバグがあります。

于 2012-11-12T16:23:40.013 に答える