我需要编写一个命令行应用程序,就像shell一样。所以它将包括命令等。事情是我不知道如何将参数传递给模块中的函数。例如:
用户写道:function1 folder1 程序现在应该将'folder1'参数传递给function1函数,然后运行它。但它也必须支持具有不同参数的其他函数ex:
用户输入:function2 folder2 --exampleparam
如何让它发挥作用?我的意思是,我可以编写一个模块,在python中导入它并只使用python控制台,但事实并非如此。我需要一个接受命令输入并运行它的脚本。
我尝试使用eval(),但这并没有解决params的问题。或许它确实如此,但我没有看到它?
答案 0 :(得分:6)
问题的第一部分 - 解析命令行 - 可以使用argparse解决。
第二部分 - 将函数的字符串名称转换为函数调用 - 可以使用exec或从字符串映射到函数对象的调度字典来完成。
我建议使用exec
NOT ,因为
允许用户从命令行调用任意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
答案 1 :(得分:2)
optparse
已弃用,无论如何argparse更灵活。
unutbu的方法是安全的,但如果你提供白名单,我建议你让用户知道哪些功能被接受
dispatch = {
'foo': foo,
'bar': bar,
}
parser = argparse.ArgumentParser()
parser.add_argument('function', choices=dispatch.keys() )
仅供参考:如果解析不是太复杂,docopt看起来就像一个非常好的包
答案 2 :(得分:1)
sys.argv怎么样?如需更高级的内容,请查看argsparse。 optparse
现在似乎已经贬值了,但这里有一个关于这个问题的lot of answers。
答案 3 :(得分:1)
看一下python中的 optparse 模块。这正是你需要的:
http://docs.python.org/2/library/optparse.html
或者您可以编写自己的自定义选择解析器(虽然简约)
def getopts(argv):
opts = {}
while argv:
if argv[0][0] == '-': # find "-name value" pairs
opts[argv[0]] = argv[1] # dict key is "-name" arg
argv = argv[2:]
else:
argv = argv[1:]
return opts
if __name__ == '__main__':
from sys import argv # example client code
myargs = getopts(argv)
# DO something based on your logic here
但是如果你的脚本需要在python 3及更高版本上运行,你需要考虑argparse模块。\
希望有所帮助。
答案 4 :(得分:0)
答案 5 :(得分:0)
import sys
def main(arg):
return arg
print main(sys.argv[1])
其中sys.argv [0]是您正在运行的.py文件,之后的所有文件都是每个参数。你可以检查列表的长度,然后遍历它,并根据需要解析它们并将正确的东西传递给每个函数