实现“[command] [action] [parameter]”风格的命令行界面? [英] Implementing a "[command] [action] [parameter]" style command-line interfaces?

查看:222
本文介绍了实现“[command] [action] [parameter]”风格的命令行界面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是最干净的方式来实现命令行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
}
}

这样的系统是否存在?如果没有,我将如何实现这些方面的东西?

解决方案

argparse 是完美的,特别是子命令和位置参数

  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]”风格的命令行界面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆