跳转到主要内容

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_truestore_false推理

声明类型为bool并给定默认值的参数被推理为store_truestore_false,具体取决于它们的默认值;如果命令行上给出了标志,则推断出需要与默认值相反。

例如,在

@cli.cmd
def commit(force: bool = False):
    ...

如果提供了--force,函数将以force=True调用,否则force将保持为False。


如果你喜欢使用这个库,考虑给我一些魔法网络货币

bc1qlj36t63qlgkywg83gwslcu3ehl76h2k2d6hcv2

项目详情


下载文件

下载适合您平台的应用程序。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码发行版

clii-1.0.3.tar.gz (8.0 kB 查看散列)

上传时间: 源代码

构建发行版

clii-1.0.3-py3-none-any.whl (8.7 kB 查看散列)

上传时间: Python 3

支持者