argparse
から継承するインターフェイスのすべてのプロンプトのインタープリターとしてフックされたモジュールを使用する方法はありますcmd
か?
cmd インターフェイスがline
、オプションの引数と位置引数を使用して、実行時に bash シェルで渡されたオプションと引数を解釈するのと同じ方法で、典型的なパラメーターを解釈することを望み-
ます。
argparse
から継承するインターフェイスのすべてのプロンプトのインタープリターとしてフックされたモジュールを使用する方法はありますcmd
か?
cmd インターフェイスがline
、オプションの引数と位置引数を使用して、実行時に bash シェルで渡されたオプションと引数を解釈するのと同じ方法で、典型的なパラメーターを解釈することを望み-
ます。
簡単な方法は、argparse
パーサーを作成し、無効な引数が指定された場合にline.split()
備えて関数内で解析expect
することです(無効な引数が見つかった場合は呼び出します)。SystemExit
parse_args()
sys.exit()
class TestInterface(cmd.Cmd):
__test1_parser = argparse.ArgumentParser(prog="test1")
__test1_parser.add_argument('--bar', help="bar help")
def help_test1(self): self.__test1_parser.print_help()
def do_test1(self, line):
try:
parsed = self.__test1_parser.parse_args(line.split())
except SystemExit:
return
print("Test1...")
print(parsed)
無効な引数が渡さparse_args()
れると、エラーが出力され、プログラムは終了せずにインターフェイスに戻ります。
(Cmd) test1 --unk
usage: test1 [-h] [--bar BAR]
test1: error: unrecognized arguments: --unk
(Cmd)
他のすべては、通常の使用例と同じように機能し、 のすべての機能 (ヘルプ メッセージ、関数リストなど)argparse
も維持する必要があります。cmd
ソース: https://groups.google.com/forum/#!topic/argparse-users/7QRPlG97cak
上記のセットアップを簡素化する別の方法は、以下のデコレータを使用することです。
class ArgparseCmdWrapper:
def __init__(self, parser):
"""Init decorator with an argparse parser to be used in parsing cmd-line options"""
self.parser = parser
self.help_msg = ""
def __call__(self, f):
"""Decorate 'f' to parse 'line' and pass options to decorated function"""
if not self.parser: # If no parser was passed to the decorator, get it from 'f'
self.parser = f(None, None, None, True)
def wrapped_f(*args):
line = args[1].split()
try:
parsed = self.parser.parse_args(line)
except SystemExit:
return
f(*args, parsed=parsed)
wrapped_f.__doc__ = self.__get_help(self.parser)
return wrapped_f
@staticmethod
def __get_help(parser):
"""Get and return help message from 'parser.print_help()'"""
f = tempfile.SpooledTemporaryFile(max_size=2048)
parser.print_help(file=f)
f.seek(0)
return f.read().rstrip()
これにより、追加のコマンドの定義が簡単になりparsed
、成功したparse_args()
. 無効な引数がある場合、関数は入力されず、すべてデコレータによって処理されます。
__test2_parser = argparse.ArgumentParser(prog="test2")
__test2_parser.add_argument('--foo', help="foo help")
@WrapperCmdLineArgParser(parser=__test2_parser)
def do_test2(self, line, parsed):
print("Test2...")
print(parsed)
argparse
関数を定義する必要なく、生成されたヘルプ メッセージを含め、すべてが元の例としてhelp_command()
機能します。
ソース: https://codereview.stackexchange.com/questions/134333/using-argparse-module-within-cmd-interface