問題的第一部分 - 解析命令行 - 可以用argparse來解決。
第二部分 - 將函數的字符串名稱轉換爲函數調用 - 可以使用exec或從字符串映射到函數對象的調度字典完成。
我會建議使用exec
這不,因爲 允許用戶從命令行調用任意Python的功能可能是危險的。相反,要允許的功能,白名單:
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 module,如評論中提到的@chepner。
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's excellent tutorial.
運行上述代碼產生這樣的結果:
% 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
第二部分,請看'cmd'模塊。 – chepner
這適用於我,但我仍然無法弄清楚如何從另一個腳本實際啓動命令。如果我把它放到模塊中的一個函數中,並像這樣調用它:module.function,什麼都不會發生。但是,如果我這樣做:module.function 1,我得到一個語法錯誤。由於該函數沒有任何參數,因此沒有必要使用參數module.function(param)調用它。 我是Python的新手,並且不幸的是還沒有真正掌握它。 –
試試'import module; module.function()'調用'module'中定義的'function'。 – unutbu