问题描述
什么是最干净的方式来实现命令行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 appappname build v1
jump_to_folder app theappname build 1
jump_to_folder app appappa v2 build
jump_to_folder
是脚本名称, app
是命令, theappname
是一个固定位置参数,build和v2等是参数(例如,可能的参数是任何数字/任何以av为前缀的数字, / source / tmp / config)
我可以手动解析一系列的参数 if
c $ c> else / elifs
,但是必须有更优雅的方式才能做到这一点?
作为一个完全理论的例子,我可以描述UI模式。
app:
fixed :application_name
可选参数:
arg子部分:
build
source
tmp
config
arg版本:
整数
v+整数
然后通过上面的模式解析提供的参数,并得到一个字典:
> print schema.parse([app,theappname,v1,source])
{
application_name:theappname,
params:{
subsection:source,
version:v1
}
}
这样的系统是否存在?如果没有,我将如何实现这些方面的东西?
解决方案是完美的,特别是和位置参数
import argparse
def main():
arger = argparse.ArgumentParser()
#顶级参数,例如subcmds.py -v
arger.add_argument -v,--verbose,action =count,default = 0)
subparsers = arger.add_subparsers(dest =command)
parcm forsubcmds.py info ...
info_parser = subparsers.add_parser(info)
info_parser.add_argument( - m,--moo,dest =moo)
#为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 opts
if opts.command ==info:
printInfo command
print--moo was%s%opts.moo
elif opts.command ==create:
printCreating%s%opts.name
printAdditional:%s%opts.additional
else:
#argparse将意外的命令错误,但
#如果我们错误的其中一个elif语句...
raise ValueError(Unhandled command%s %opts.command)
如果__name__ =='__main__':
main()
这样可以使用:
$ python subcmds.py create myapp v1 blah
命名空间(additional = ['v1','blah'],command ='create',name ='myapp',verbose = 0)
创建myapp
','blah']
$ python subcmds.py info --moo
用法:subcmds.py info [-h] [-m MOO]
subcmds.py info:error:argument -m / - moo:expect一个参数
$ python subcmds.py info --moo 1
命名空间(command ='info',moo ='1',verbose = 0)
信息命令
--moo is 1
What is the "cleanest" way to implement an command-line UI, similar to git's, for example:
git push origin/master git remote add origin git://example.com master
Ideally also allowing the more flexible parsing, for example,
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
is the scripts name,app
is the command,theappname
is a "fixed-location" parameter, "build" and "v2" etc are arguments (For example, possible arguments would be any number/any number prefixed with a v, or build/source/tmp/config)I could just manually parse the arguments with a series of
if
/else
/elifs
, but there must be a more elegant way to do this?As an entirely theoretically example, I could describe the UI schema..
app: fixed: application_name optional params: arg subsection: "build" "source" "tmp" "config" arg version: integer "v" + integer
Then parse the supplied arguments though the above schema, and get a dictionary:
>>> print schema.parse(["app", "theappname", "v1", "source"]) { "application_name": "theappname", "params":{ "subsection": "source", "version":"v1" } }
Does such a system exist? If not, how would I go about implementing something along these lines?
解决方案argparse is perfect for this, specifically "sub-commands" and positional args
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()
This can be used like so:
$ 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
这篇关于实现“[command] [action] [parameter]”风格的命令行界面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!