Python函数 -> CLI
项目描述
clii
使用Python 3函数注释从Python函数生成最小样板代码的解析器。
#!/usr/bin/env python3.8
from clii import App
from pathlib import Path
from subprocess import run
cli = App()
@cli.cmd
def add(a: int, b: int = 3):
print(a + b)
@cli.cmd
@cli.arg('path', '-p', help='Destroy where?')
def subtract(path: Path):
run(f'rm -rf {path}')
@cli.main
def main():
print(f"{add(1, 2)} and {subtract('/uhoh')}")
if __name__ == '__main__':
cli.run()
-
无依赖项。 此库没有依赖项,是一个单独的文件。你想将其作为供应商使用吗?使用它。
-
简短实现。 用10分钟,浏览实现,相信自己没有窃取你的
id_rsa
,然后使用这个小程序,永远不再想任何事情。 -
无需学习。 如果你知道如何使用Python函数注释,你已经知道了这个库的98%。
-
针对常见情况进行优化。 查看代码
test_bad_git.py
。我知道你想做什么(创建一个次等的git的复制品),我已经使其简洁。 -
函数仍然可以作为普通函数使用。 你仍然可以像平常一样调用装饰过的函数,无需任何特殊仪式。装饰器仅用于构建解析器。
好吧,你我都知道每个人都不需要另一种生成命令行界面的方法。仅仅为了在你的项目中添加一个额外的依赖项,以便学习另一种仅稍微比stdlib界面更易于使用的解析args的方法,这与用任何一种当周基于JavaScript的构建系统重写所有Makefiles一样,我理解。
是的,我应该做些真正有用的事情,比如尝试找到一个生活伴侣或看看在X-Files一集中我能喝多少谷物酒精,但每次我输入一些过于冗长的argparse
咒语,这是我一年中第16次在docs.python.org上查找,我心中最后一点童真的计算变成了盘腿而坐,并自燃。
Click相当于请建筑师来修理你的厨房水槽。代码很多,界面冗长且不直观。Docopt很整洁,但速度慢,是新鲜事物,代码量也很大,我每次使用它之前都必须阅读3个例子。Argparse是一个还不错的内置库,是这个库的尊贵祖先,但它过于冗长,连接子解析器调用函数的常见任务很痛苦。
不要燃烧你的童真。使用函数注解。使用这个愚蠢的库。
安装
# Requires Python >=3.7
python3 -m pip install --user clii
大量使用示例
#!/usr/bin/env python3
"""
A really lame version of git.
"""
from pathlib import Path
import typing as t
from clii import App
cli = App(description=__doc__)
cli.add_arg('--verbose', '-v', action='store_true', default=False)
@cli.cmd
def clone(url: str, target: Path, branch: t.Optional[str] = None):
"""Clone the branch so you can melt your computer."""
branch = f' -b {branch}' if branch else ''
# We can reference global args since all parsed arguments are attached
# to `cli.args` after parsing.
if cli.args.verbose:
print(f'git clone{branch} {url} {target}')
@cli.cmd
def push(remote: str, branch: str, force: bool = False):
force_flag = ' -f' if force else ''
if cli.args.verbose:
print(f'git push{force_flag} {remote} {branch}')
@cli.cmd
@cli.arg('all', '-a') # add a short flag, or any other argparse setting
@cli.arg('message', '-m')
def commit(all: bool = False, message: str = ''):
# Arguments are --all, -a and --message, -m
print(all)
print(message)
@cli.cmd
@cli.arg('updated', '-u')
def add(*files, updated: bool = False):
# `files` will be a variadic positional arg, while --updated/-u is a bool
# flag.
if cli.args.verbose:
print(f"adding files: {files}")
if __name__ == '__main__':
cli.run()
然后你将得到
% ./test_bad_git.py --help
usage: test_bad_git.py [-h] [--verbose] {clone,push,commit,add} ...
A really lame version of git.
positional arguments:
{clone,push,commit,add}
optional arguments:
-h, --help show this help message and exit
--verbose, -v
% ./test_bad_git.py clone --help
usage: test_bad_git.py clone [-h] [--branch BRANCH] url target
Clone the branch so you can melt your computer.
positional arguments:
url
target
optional arguments:
-h, --help show this help message and exit
--branch BRANCH default: None
使用说明
使用@App.main
添加主命令
使用@cli.main
装饰器装饰任何函数意味着该函数在没有函数参数的情况下是默认选择的子解析器。
使用@cli.arg(...)
添加add_argument
参数
您可以使用@cli.arg('paramname', <additional args>...)
装饰器为给定参数添加任意ArgumentParser.add_argument(...)
参数。
此装饰器必须应用于@cli.cmd
装饰器之后的行。
来自文档字符串的帮助文本
clii将从格式如下
import clii
cli = clii.App()
@cli.cmd
def foo(bar: str):
"""
Args:
bar: some kind of helpful docstring.
"""
cli.run()
具体来说,文档字符串将搜索" [参数名称]:" - 如果找到该模式,冒号之后的内用作为帮助文本。
store_true
和store_false
推理
声明类型为bool并给定默认值的参数被推理为store_true
或store_false
,具体取决于它们的默认值;如果命令行上给出了标志,则推断出需要与默认值相反。
例如,在
@cli.cmd
def commit(force: bool = False):
...
如果提供了--force
,函数将以force=True
调用,否则force
将保持为False。
如果你喜欢使用这个库,考虑给我一些魔法网络货币
bc1qlj36t63qlgkywg83gwslcu3ehl76h2k2d6hcv2
项目详情
下载文件
下载适合您平台的应用程序。如果您不确定选择哪个,请了解更多关于安装包的信息。
源代码发行版
构建发行版
clii-1.0.3.tar.gz的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 8ffcbb7b89cb87c1f419ff3eb19e77111dac73bc9b55cd3f8d164b331c4922c1 |
|
MD5 | 372be5284ae2fefeaf9efd8344117b5b |
|
BLAKE2b-256 | cd3ceddeb83b13848d25cb7e6e29f68667232cdae303759c7c332a8d0687a25f |