ソースをいじる以外に、必要なスイッチがないなど、呼び出されargparse
たときに問題が発生した場合に、終了ステータス コードを制御する方法はありますか?parse_args()
8 に答える
引数ごとに終了コードを指定するメカニズムを知りません。SystemExit
発生した例外をキャッチできますが、エラーの具体的な原因を特定.parse_args()
する方法がわかりません。
編集:実用的な解決策を探してこれに来る人にとって、次のような状況があります:
ArgumentError()
引数の解析が失敗したときに適切に発生します。引数インスタンスとメッセージが渡されますArgumentError()
渡されたにもかかわらず、引数をインスタンス属性として保存しません(これは便利です)ArgumentError
.error() をサブクラス化ArgumentParser
し、オーバーライドし、sys.exc_info() から例外を取得することで、例外を再発生させることができます。
つまり、次のコードは (見苦しいですが)、ArgumentError 例外をキャッチし、問題のある引数とエラー メッセージを取得して、必要に応じて実行できることを意味します。
import argparse
import sys
class ArgumentParser(argparse.ArgumentParser):
def _get_action_from_name(self, name):
"""Given a name, get the Action instance registered with this parser.
If only it were made available in the ArgumentError object. It is
passed as it's first arg...
"""
container = self._actions
if name is None:
return None
for action in container:
if '/'.join(action.option_strings) == name:
return action
elif action.metavar == name:
return action
elif action.dest == name:
return action
def error(self, message):
exc = sys.exc_info()[1]
if exc:
exc.argument = self._get_action_from_name(exc.argument_name)
raise exc
super(ArgumentParser, self).error(message)
## usage:
parser = ArgumentParser()
parser.add_argument('--foo', type=int)
try:
parser.parse_args(['--foo=d'])
except argparse.ArgumentError, exc:
print exc.message, '\n', exc.argument
有用な方法でテストされていません。通常の「壊れたら責めないで」の補償が適用されます。
すべての回答は、argparse実装の詳細をうまく説明しています。
実際、PEPで提案されている(そして Rob Cowie によって指摘されている)ように、 ArgumentParserを継承し、エラーまたは終了メソッドの動作をオーバーライドする必要があります。
私の場合、エラーが発生した場合に使用状況の印刷を完全なヘルプの印刷に置き換えたかっただけです。
class ArgumentParser(argparse.ArgumentParser):
def error(self, message):
self.print_help(sys.stderr)
self.exit(2, '%s: error: %s\n' % (self.prog, message))
オーバーライドの場合、メイン コードには最小限のものが引き続き含まれます。
# Parse arguments.
args = parser.parse_args()
# On error this will print help and cause exit with explanation message.
おそらく、SystemExit
例外をキャッチすることは簡単な回避策になるでしょう:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('foo')
try:
args = parser.parse_args()
except SystemExit:
print("do something else")
インタラクティブなセッションでも機能します。
編集: @Rob Cowieが私をスイッチに打ち負かしたようです。彼が言ったように、愚かになってトレースバックから情報を収集しようとしない限り、これには診断の可能性はあまりありません。
Python 3.9 の時点で、これはそれほど苦痛ではなくなりました。これは、新しいargparse.ArgumentParser
exit_on_error
インスタンス化引数を介して処理できるようになりました。以下に例を示します (python ドキュメントから少し変更: argparse#exit_on_error ):
parser = argparse.ArgumentParser(exit_on_error=False)
parser.add_argument('--integers', type=int)
try:
parser.parse_args('--integers a'.split())
except argparse.ArgumentError:
print('Catching an argumentError')
exit(-1)
既存のメソッドの 1 つを使用できます: http://docs.python.org/library/argparse.html#exiting-methods。ただし、引数が無効な状況は既に処理されているはずです (引数を適切に定義していると仮定します)。
無効な引数の使用:
% [ $(./test_argparse.py> /dev/null 2>&1) ] || { echo error }
error # exited with status code 2
いじくり回す必要があります。argparse.ArgumentParser.error
内部で呼び出される を見てください。または、引数を非必須にしてから、argparse の外でチェックして終了することもできます。