服务端程序实际运行时总会需要一些外部参数,一般情况下读取固定路径的配置即可。但有时候运维需要自由调整程序的运行姿势,需要灵活一点的配置方式。我尝试了下 CLI (Command-line interface) ,开发和运维用了都说好,大家一口气上五楼。
大家用着是爽了,但我实现起来总有些磕碰,遂忍不住多尝试了几种方案。
没啥特点,只按部就班提供诸如添加参数、子命令和参数类型转换之类的 API. 使用这些 API 构造出 parser 去解析命令行输入。
有点潮,只需完整地写出 Help 文本(DSL 语法就是 Help 内容),其通过解析该文本来生成 parser。非常直观,不依赖任何语言特性,于是所有语言都能实现一致的体验,实际上也都实现了。但和 argparse 一样只是个 parser ,需要额外编码去调用具体的函数。
这一类的使用体验是最好的,只需实现函数本身,外加一点注解、注释就能自动生成 parser 和函数 binding。 比较依赖语言的特性,至少也得有反射机制才行。比如 Python 连注释(docstring)都能在运行时获得,于是就有 cbox 这样的实现。使用非常简单,我还给它加了子命令支持。
附上 cbox 的子命令实现参考,来自我的 PR。
https://github.com/shmuelamar/cbox/pull/4
import cbox
@cbox.cmd
def hello(name: str):
"""
greets a person by its name.
:param name: the name of the person
"""
print('hello name={name}!'.format(**locals()))
@cbox.cmd
def world(name: str):
"""
greets a person by its name.
:param name: the name of the person
"""
print('world name={name}!'.format(**locals()))
if __name__ == '__main__':
cbox.main([hello, world])
以上,表现力绝赞!无需多余代码即可自动生成命令行接口。
$ python yourscript.py --help
usage: subcommands.py [-h] {hello,world} ...
which subcommand do you want?
optional arguments:
-h, --help show this help message and exit
subcommands:
{hello,world}
hello greets a person by its name.
world greets a person by its name.
完。