使用docopt创建基于子命令的cli程序
docopt-subcommands的Python项目详细描述
docopt子命令
docopt子命令的简单实现。
docopt-subcommands
允许您创建基于子命令的程序
使用docopt。基于子命令的程序是
其中主程序使用一个“subcommand”参数来告诉它
去吧。
这种程序的典型例子是git。这个git
没有参数的命令没有什么作用。相反,这是第一次
参数git
-子命令告诉它实际要做什么。为了
示例:
git log
将为您提供存储库的日志。同样:
git rebase
是用于重新定位的子命令。
docopt-subcommands
可以帮助您创建类似类型的命令行
使用docopt
的工具。
快速启动
docopt-subcommands
背后的基本思想很简单:
- 为每个子命令提供单独的handler函数。
- 每个处理程序函数的docstring定义 该子命令。
- 使用以下子命令的名称注册处理程序函数 将调用它们。
- 提供程序名和(可选)顶级文档字符串。
然后docopt-subcommands
将所有东西缝合成
子命令驱动程序。下面是它的外观
exampels/basic_example.py
):
# Basic, most common usage of docopt_subcommandsimportdocopt_subcommandsasdsc# 1. Use the `command` decorator to add subcommands functions.@dsc.command()deffoo_handler(precommand_args,args):"""usage: {program} foo <name> Apply foo to a name. """print("Foo, {}".format(args['<name>']))@dsc.command()defbar_handler(precommand,args):"""usage: {program} bar <name> Apply bar to a name. """print("Bar, {}".format(args['<name>']))# 2. Pass a program name and version string to `main` to run a program with the# subcommands you defined with the decorators above.dsc.main(program='docopt-subcommand-example')
如果你在命令行运行这个程序,你会发现你有一个很好的, 基于子命令的cli程序:
$ python basic_example.py Usage: docopt-subcommand-example [options] <command> [<args> ...] $ python basic_example.py -h docopt-subcommand-example Usage: docopt-subcommand-example [options] <command> [<args> ...] Options: -h --help Show this screen. Available commands: bar foo See 'docopt-subcommand-example help <command>'forhelp on specific commands. $ python basic_example.py foo usage: docopt-subcommand-example foo <name> $ python basic_example.py foo -h usage: docopt-subcommand-example foo <name> Apply foo to a name. $ python basic_example.py foo Bubba Foo, Bubba
有关更多示例,请参见examples
目录。
常用选项
许多基于子命令的程序都有一组对所有命令都通用的选项。一个常见的例子是--verbose
这会导致程序打印更多信息,而不管执行哪个命令。使用docopt_subcommands
可以在顶级docstring中指定这些常用选项,如下所示:
顶级文档=“{program}
用法:{program}[options]<;command>;[<;args>;..]
选项: -H—帮助显示此屏幕 --详细使用详细输出
可用命令: {可用的命令} “”“
使用此docstring,可以为任何子命令提供--verbose
标志。关键的是,公共选项必须在子命令名称之前提供。因此,如果bar
是程序中的子命令,您将编写:
我的程序--详细栏
但不是:
我的程序栏--详细
docopt_subcommands
分两次解析完整的命令行。第一次传递使用顶级
docstring,而第二个过程使用docstring作为特定命令,并且只解析命令行的一部分
在共同的选择之后。然后,它向子命令处理程序提供两个解析的dict:
handler是第一次传递的结果,第二个参数是第二次传递的结果。
在这个系统中,您可以使用一组代码为您的程序执行“公共配置”。例如, 处理程序的外观如下:
。代码块::python
@dsc.command() def bar_handler(预命令参数,参数): “用法:{program}bar<;name>;
Apply bar to a name.
"""
handle_common_option(precommand_args)
name = args['<name>']
print('Bar {}'.format(name))
高级用法
对于大多数用户,“快速启动”中描述的基本用法应该是您所需要的,
但有些用户需要对docopt_subcommands
进行更多的控制。这个
docopt_subcommands.main()
我们之前使用的只是一个方便
在真正的工作马之上,docopt_subcommands.Subcommands
。你可以
直接实例化这个类,绕过main()
,并在您
在实际调用命令行处理之前需要。
在大多数情况下,Subcommands
初始值设定项的参数非常
类似于main()
。这反映出main()
实际上
实例化一个Subcommands
实例(如果您没有提供),填充它
使用命令,并使用命令行参数调用它。你可以做所有的
如果你需要的话,你可以自己走。
作为一个例子,如果您构造一个
Subcommands
直接实例。
importdocopt_subcommandsasdscimportsyssc=dsc.Subcommands(program='docopt-subcommand-example')@sc.command('foo')deffoo_handler(args):"""usage: {program} {command} <name> Apply foo to a name. """print("Foo, {}".format(args['<name>']))@sc.command('bar')defbar_handler(args):"""usage: {program} {command} <name> Apply bar to a name. """print("Bar, {}".format(args['<name>']))sc(sys.argv[1:])
如您所见,它与基本示例没有本质上的不同。
main()
主要是通过选择
一些事情的合理默认值-使用此方法会丢失。