实现命令行UI的“最干净”方式是什么,类似于git,例如:
git push origin/master
git remote add origin git://example.com master
理想情况下还允许更灵活的解析,例如
jump_to_folder app theappname v2
jump_to_folder app theappname source
jump_to_folder app theappname source v2
jump_to_folder app theappname build v1
jump_to_folder app theappname build 1
jump_to_folder app theappname v2 build
jump_to_folder
是脚本名称,app
是命令,theappname
是“固定位置”参数,“build”和“v2”等是参数(例如,可能的参数是任何数字/任何以av或build / source / tmp / config为前缀的数字
我可以使用一系列if
/ else
/ elifs
手动解析参数,但必须有更优雅的方法来执行此操作吗?
作为一个完全理论上的例子,我可以描述UI模式..
app:
fixed: application_name
optional params:
arg subsection:
"build"
"source"
"tmp"
"config"
arg version:
integer
"v" + integer
然后通过上面的模式解析提供的参数,并得到一个字典:
>>> print schema.parse(["app", "theappname", "v1", "source"])
{
"application_name": "theappname",
"params":{
"subsection": "source",
"version":"v1"
}
}
这样的系统存在吗?如果没有,我将如何沿着这些方向实施某些内容?
答案 0 :(得分:16)
argparse非常适用于此,特别是"sub-commands"和位置参数
import argparse
def main():
arger = argparse.ArgumentParser()
# Arguments for top-level, e.g "subcmds.py -v"
arger.add_argument("-v", "--verbose", action="count", default=0)
subparsers = arger.add_subparsers(dest="command")
# Make parser for "subcmds.py info ..."
info_parser = subparsers.add_parser("info")
info_parser.add_argument("-m", "--moo", dest="moo")
# Make parser for "subcmds.py create ..."
create_parser = subparsers.add_parser("create")
create_parser.add_argument("name")
create_parser.add_argument("additional", nargs="*")
# Parse
opts = arger.parse_args()
# Print option object for debug
print opts
if opts.command == "info":
print "Info command"
print "--moo was %s" % opts.moo
elif opts.command == "create":
print "Creating %s" % opts.name
print "Additional: %s" % opts.additional
else:
# argparse will error on unexpected commands, but
# in case we mistype one of the elif statements...
raise ValueError("Unhandled command %s" % opts.command)
if __name__ == '__main__':
main()
这可以这样使用:
$ python subcmds.py create myapp v1 blah
Namespace(additional=['v1', 'blah'], command='create', name='myapp', verbose=0)
Creating myapp
Additional: ['v1', 'blah']
$ python subcmds.py info --moo
usage: subcmds.py info [-h] [-m MOO]
subcmds.py info: error: argument -m/--moo: expected one argument
$ python subcmds.py info --moo 1
Namespace(command='info', moo='1', verbose=0)
Info command
--moo was 1
答案 1 :(得分:9)
cmd
模块可能适用于此。
示例:
import cmd
class Calc(cmd.Cmd):
def do_add(self, arg):
print sum(map(int, arg.split()))
if __name__ == '__main__':
Calc().cmdloop()
运行它:
$python calc.py
(Cmd) add 4 5
9
(Cmd) help
Undocumented commands:
======================
add help
(Cmd)
有关详细信息,请参阅Python docs或PyMOTW site。
答案 2 :(得分:2)
直接来自我的一个剧本:
import sys
def prog1_func1_act1(): print "pfa1"
def prog2_func2_act2(): print "pfa2"
commands = {
"prog1 func1 act1": prog1_func1_act1,
"prog2 func2 act2": prog2_func2_act2
}
try:
commands[" ".join(sys.argv[1:])]()
except KeyError:
print "Usage: ", commands.keys()
这是一个非常快速和肮脏的解决方案,但对我的使用非常有用。如果我要稍微清理它,我可能会在混合中添加argparse来解析位置和关键字参数。
答案 3 :(得分:1)
Python有一个用于解析命令行选项的模块optparse。
答案 4 :(得分:1)
答案 5 :(得分:0)
这是我的建议。
略微改变你的语法。
使用optparse。
理想情况下还允许更灵活的解析,例如
jump_to_folder -n theappname -v2 cmd
jump_to_folder -n theappname cmd source
jump_to_folder -n theappname -v2 cmd source
jump_to_folder -n theappname -v1 cmd build
jump_to_folder -n theappname -1 cmd build
jump_to_folder -n theappname -v2 cmd build
然后你有1或2个args:命令总是第一个arg。它的可选参数始终是第二个参数。
其他一切都是选项,没有特别的顺序。