問題の最初の部分 (コマンド ラインの解析) はargparseで解決できます。
2 番目の部分 (関数の文字列名を関数呼び出しに変換する) は、文字列から関数オブジェクトにマップするexecまたはディスパッチ dict を使用して実行できます。
ユーザーがコマンドラインから任意の Python 関数を呼び出せるようにすることは危険な場合があるため、これには使用しないことをお勧めします。exec
代わりに、許可される機能のホワイトリストを作成します。
import argparse
def foo(path):
print('Running foo(%r)' % (path, ))
def bar(path):
print('Running bar(%r)' % (path, ))
dispatch = {
'foo': foo,
'bar': bar,
}
parser = argparse.ArgumentParser()
parser.add_argument('function')
parser.add_argument('arguments', nargs='*')
args = parser.parse_args()
dispatch[args.function](*args.arguments)
% test.py foo 1
Running foo('1')
% test.py bar 2
Running bar('2')
% test.py baz 3
KeyError: 'baz'
上記は、コマンドがコマンドライン自体に入力されたときに機能します。コマンドが に入力されている場合はstdin
、少し異なることを行う必要があります。
簡単な方法は、 を呼び出しraw_input
て から文字列を取得することstdin
です。次に、上記のように、argparse を使用して文字列を解析できます。
shmod.py :
import argparse
def foo(path):
print('Running foo(%r)' % (path, ))
def bar(path):
print('Running bar(%r)' % (path, ))
dispatch = {
'foo': foo,
'bar': bar,
}
def parse_args(cmd):
parser = argparse.ArgumentParser()
parser.add_argument('function')
parser.add_argument('arguments', nargs='*')
args = parser.parse_args(cmd.split())
return args
main.py :
import shmod
while True:
cmd = raw_input('> ')
args = shmod.parse_args(cmd)
try:
shmod.dispatch[args.function](*args.arguments)
except KeyError:
print('Invalid input: {!r}'.format(cmd))
これを処理する別のより洗練された方法は、コメントで言及されているように、 cmd モジュールを使用することです。
from cmd import Cmd
class MyInterpreter(Cmd):
prompt = '> '
def do_prompt(self, line):
"Change the interactive prompt"
self.prompt = line + ': '
def do_EOF(self, line):
return True
def do_foo(self, line):
print('Running foo {l}'.format(l=line))
def do_bar(self, line):
print('Running bar {l}'.format(l=line))
if __name__ == '__main__':
MyInterpreter().cmdloop()
cmd モジュールの使用方法の詳細については、Doug Hellman の優れたチュートリアルを参照してください。
上記のコードを実行すると、次のような結果が得られます。
% test.py
> foo 1
Running foo 1
> foo 1 2 3
Running foo 1 2 3
> bar 2
Running bar 2
> baz 3
*** Unknown syntax: baz 3