2016-07-12 16 views
3

私はargparseを使用してコマンドライン引数を解析しています。デフォルトで無効な引数を受け取ると、ヘルプメッセージが出力されて終了します。無効な引数を受け取ったときにargparseの動作をカスタマイズすることは可能ですか?Pythonでargparseで無効な引数を処理する

一般的に、私はすべての無効な引数をキャッチして、それらでいっぱいにしたい。私が持つことができるように

parser = argparse.ArgumentParser() 
# add some arguments here 
try: 
    parser.parse_args() 
except InvalidArgvsError, iae: 
    print "handle this invalid argument '{arg}' my way!".format(arg=iae.get_arg()) 

:私のようなものを探しています

>> python example.py --invalid some_text 
handle this invalid argument 'invalid' my way! 
+0

あなたがすでに引数にあなたの方法を扱っていることが表示されます:あなたが印刷されましたメッセージ内の無効な引数あなたの問題は何ですか? – Prune

+0

@Prune: 'InvalidArgsError'のようなものはありません。投稿されたコードは実際には機能しません。 – user2357112

+0

私はそのようなエラーはないことを認識します。しかし、OPはうまくいっている。私はレトリックの問題があると思う。ありがとう。 – Prune

答えて

3

あなたは何であったかの引数を参照するためにparse_known_argsを使用して、タプルの2番目の項目を見てみたいことがあります理解されていない。

これは、extra引数でのみ有効であり、無効な値を持つ引数ではないと考えています。

+0

これは 'argparse'が提供する最良のオプションのようです。 – user2357112

1

argparse.ArgumentParser(をサブクラス化し、errorメソッドをオーバーライドすることができます。

argparseソースから:

def error(self, message): 
     """error(message: string) 

     Prints a usage message incorporating the message to stderr and 
     exits. 

     If you override this in a subclass, it should not return -- it 
     should either exit or raise an exception. 
     """ 
     self.print_usage(_sys.stderr) 
     self.exit(2, _('%s: error: %s\n') % (self.prog, message)) 
+1

それは他のあらゆる種類のエラーに使用されますが、メッセージ文字列以外にもカスタムエラー処理に役立つ情報にはアクセスできません。 – user2357112

+0

@ user2357112ええ、それは本当ですが、他の選択肢は、parse_args()/ parse_known)_args()自体をオーバーライドするか、まったく便利ではないすべてのメソッドで干渉することです。 –

+0

私はargparseエラーメソッドを修正するための深刻な試みは認識していません。このモジュールはいくつかの初歩的な 'Error'クラスを定義していますが、あまりそれをしません。 'ArgumentError'は引数名をメッセージに追加するだけです。 – hpaulj

2

いくつかの以前の質問:

Python argparse and controlling/overriding the exit status code

I want Python argparse to throw an exception rather than usage

、おそらくより。

argparseのドキュメントでは、parse_known_argsの使用について説明しています。これは、認識できない引数のリストを返します。 1つのタイプのエラーを処理する便利な方法です。

また、独自のerrorexitメソッドの作成方法についても説明します。あなたが好きではないそのエラーは、それらの2つの方法を通過します。それらを変更する適切な方法はサブクラスArgumentParserですが、既存のパーサーをサルキーパッチすることもできます。デフォルトのバージョンはargparse.pyファイルの末尾にあるので、あなたが行っていることを勉強することができます。

3番目のオプションは、Systemexitを試してみることです。

try: 
    parser=argparse.ArgumentParser() 
    args=parser.parse_args() 
except SystemExit: 
    exc = sys.exc_info()[1] 
    print(exc) 

このようにして、エラー/終了によってエラーメッセージ(sys.stderr)が生成されますが、終了をブロックしてその他のことを行うことができます。以前の質問の

1649:~/mypy$ python stack38340252.py -x 
usage: stack38340252.py [-h] 
stack38340252.py: error: unrecognized arguments: -x 
2 

一つはparser.errorはエラーに関する多くの情報を取得していないことを訴えました。

def myerror(message): 
    print('error message') 
    print(message) 

parser=argparse.ArgumentParser() 
parser.error = myerror 
args=parser.parse_args() 

ディスプレイ

1705:~/mypy$ python stack38340252.py -x 
error message 
unrecognized arguments: -x 

あなたは-xが認識できない文字列である見つけるためにそのメッセージを解析できます。それだけでフォーマットされたメッセージを取得します。以前のバージョンに比べて改善では、エラーメッセージをトリガすることができ、すべてのケースを見てself.errorを見上げて、複数の引数

1705:~/mypy$ python stack38340252.py foo -x abc -b 
error message 
unrecognized arguments: foo -x abc -b 

を一覧表示することができます。より多くのアイデアが必要な場合は、特定のタイプのエラーに焦点を当てます。

unrecognized argumentsエラーがparse_known_argsを呼び出し、extrasが空でない場合、このエラーが発生parse_args、により製造される

===============。その特別な情報はparse_known_argsが処理できなかった文字列のリストです。

parse_known_argsは、ArgumentErrorをトラップする場合はself.errorを呼び出します。一般的には、特定の引数(Action)に問題があるときに生成されます。しかし、_parse_known_argsは、必要に応じてself.errorを呼び出します。アクションが見つからないか、相互排他グループエラーがある場合。 choicestypeのように異なるエラーを生成する可能性があります。

0

エラーコード2は、内部ドッキングウィンドウの使用のために予約されているので、私はドッキングウィンドウコンテナ内のスクリプトに引数を解析するために、次を使用しています:

ERROR_CODE = 1 
class DockerArgumentParser(argparse.ArgumentParser): 
    def error(self, message): 
     """error(message: string) 

    Prints a usage message incorporating the message to stderr and 
    exits. 

    If you override this in a subclass, it should not return -- it 
    should either exit or raise an exception. 

    Overrides error method of the parent class to exit with error code 1 since default value is 
    reserved for internal docker usage 
    """ 
    self.print_usage(sys.stderr) 
    args = {'prog': self.prog, 'message': message} 
    self.exit(ERROR_CODE, '%(prog)s: error: %(message)s\n' % args) 
関連する問題