ここで解決策を見つけたかもしれません。確かに、これは汚いハックですが、機能します。
注: 以下はすべて Python 3.3.2 に適用されます。
回答hereに従って、どのparse_args
アクションが必要かを確認し、それらのいずれかが欠落している場合はエラーをスローします。この動作をオーバーライドすることを提案します。
サブクラス化することにより、いくつかの引数が欠落しているためにエラーがスローされたかどうかをチェックし、必要なアクションを実行する新しいメソッド (オリジナルはここにありますArgumentParser
) を定義できます。コードは次のとおりです。ArgumentParser.error
import argparse
import sys
from gettext import gettext as _
class ArgumentParser(argparse.ArgumentParser):
skip_list = []
def error(self, message):
# Let's see if we are missing arguments
if message.startswith('the following arguments are required:'):
missingArgs = message.split('required: ')[1].split(', ')
newArgs = [] # Creating a list of whatever we should not skip but is missing
for arg in missingArgs:
if arg not in self.skip_list:
newArgs.append(arg)
else:
self.skip_list.remove(arg) # No need for it anymore
if len(newArgs) == 0:
return # WARNING! UNTESTED! MAY LEAD TO SPACETIME MELTDOWN!
else: # Some required stuff is still missing, so we show a corrected error message
message = _('the following arguments are required: %s') % ', '.join(newArgs)
self.print_usage(sys.stderr) # Original method behavior
args = {'prog': self.prog, 'message': message}
self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
新しいメソッドは、最初にエラーがコマンド ラインに引数がないためかどうかをチェックします (エラーを生成するコードについては、こちらを参照してください)。その場合、メソッドはエラー メッセージから引数の名前を取得し、それらをリスト ( missingArgs
) に入れます。
次に、このリストを繰り返し処理し、スキップする必要がある引数とまだ必要な引数を確認します。どの引数をスキップするかを決定するために、それらを と比較しますskip_list
。これはサブクラスのフィールドでありArgumentParser
、パーサーで必要な場合でもスキップする引数の名前が含まれている必要があります。たまたま含まれている引数skip_list
は、見つかったときに削除されることに注意してください。
コマンドラインから欠落している必要な引数がまだある場合、メソッドは修正されたエラー メッセージをスローします。ただし、欠落しているすべての引数をスキップする必要がある場合は、メソッドは戻ります。
警告!の元の定義でArgumentParser.error
は、サブクラスでオーバーライドされた場合、 を返すのではなく、終了するか、例外を発生させる必要があります。したがって、ここに示されているものは安全ではない可能性があり、プログラムがクラッシュしたり、コンピューターが発火したり、さらに悪いことに、お茶がすべて蒸発する可能性があります。ただし、この特定のケース (必要な引数がない) では、メソッドから安全に戻ることができるようです。しかし、そうではないかもしれません。あなたは警告されました。
埋めるために、次skip_list
のようなコードを使用できます。
class SpecialHelp(argparse._HelpAction):
def __call__(self, parser, namespace, values, option_string=None):
parser.print_help()
print()
for action in parser._actions:
if action != self and action.required:
parser.skip_list.append(argparse._get_action_name(action))
この特定のクラスは組み込みhelp
アクションを模倣しますが、終了する代わりに、残りの必要な引数をすべて に挿入しskip_list
ます。
私の答えがお役に立てば幸いです。