命令链的别名

2024-01-12

我有一个tool使用命令:step1, step2 and step3.

我可以通过调用以下方式链接它们:

$ tool step1 step2 step3

我想要一个名为all通过调用以下命令来运行所有步骤:

$ tool all

我找到了一个可行的解决方案,但它似乎不适合我,因为调用cli()在引擎盖下两次:

@click.group(chain=True)
def cli():
    print('cli() has been called')

...

@cli.command()
def all():
    cli(args=['step1', 'step2', 'step3'])

还有什么办法可以在没有调用副作用的情况下完成此操作cli() twice?


提供一些别名的一种方法是拦截命令并直接操作args列表。这可以通过自定义类来完成,例如:

定制类

这个类重写了click.Group.__call__()方法允许编辑args在调用命令处理器之前列出。此外它还覆盖format_epilog添加别名的帮助文档。

class ExpandAliasesGroup(click.Group):

    def __init__(self, *args, **kwargs):
        self.aliases = kwargs.pop('aliases', {})
        super(ExpandAliasesGroup, self).__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if args and args[0] and args[0][0] in self.aliases:
            alias = self.aliases[args[0][0]]
            args[0].pop(0)
            for command in reversed(alias):
                args[0].insert(0, command)
        return super(ExpandAliasesGroup, self).__call__(*args, **kwargs)

    @property
    def alias_help(self):
        return '\n'.join(
            '{}:  {}'.format(alias, ' '.join(commands))
            for alias, commands in sorted(self.aliases.items())
        )

    def format_epilog(self, ctx, formatter):
        """Inject our aliases into the help string"""

        if self.aliases:
            formatter.write_paragraph()
            formatter.write_text('Aliases:')
            with formatter.indentation():
                formatter.write_text(self.alias_help)

        # call the original epilog
        super(ExpandAliasesGroup, self).format_epilog(ctx, formatter)

使用自定义类

通过通过cls参数,以及别名的字典click.group()装饰师,ExpandAliasesGroup类可以进行别名扩展。

aliases = dict(all='command1 command2 command3'.split())

@click.group(chain=True, cls=ExpandAliasesGroup, aliases=aliases)
def cli():
    ....

这是如何运作的?

这是可行的,因为 click 是一个设计良好的 OO 框架。这@click.group()装饰器通常会实例化一个click.Group对象,但允许此行为被覆盖cls范围。所以继承是一件比较容易的事情click.Group在我们自己的类中并重写所需的方法。

通过重写__call__方法我们可以拦截所有命令调用。然后,如果参数列表以已知别名开头,我们通过删除该别名命令并将其替换为别名来编辑参数列表。

通过重写format_epilog方法我们可以为别名添加帮助文档。

测试代码:

import click

aliases = dict(all='command1 command2 command3'.split())

@click.group(cls=ExpandAliasesGroup, chain=True, aliases=aliases)
def cli():
    pass

@cli.command()
def command1():
    click.echo('Command 1')

@cli.command()
def command2():
    click.echo('Command 2')

@cli.command()
def command3():
    click.echo('Command 3')

if __name__ == "__main__":
    commands = (
        'command1',
        'command3',
        'command1 command2',
        'all',
        '--help',
    )

    for cmd in commands:
        try:
            print('-----------')
            print('> ' + cmd)
            cli(cmd.split())
        except:
            pass        
    

检测结果:

-----------
> command1
Command 1
-----------
> command3
Command 3
-----------
> command1 command2
Command 1
Command 2
-----------
> all
Command 1
Command 2
Command 3
-----------
> --help
Usage: test.py [OPTIONS] COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]...

Options:
  --help  Show this message and exit.

Commands:
  command1  Command #1 comes first
  command2  Command #2 is after command #1
  command3  Command #3 saves the best for last

Aliases:
  all:  command1 command2 command3
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

命令链的别名 的相关文章

  • 在 Python 中解析 TCL 列表

    我需要在双括号上拆分以空格分隔的 TCL 列表 例如 OUTPUT 172 25 50 10 01 01 Ethernet 172 25 50 10 01 02 Ethernet Traffic Item 1 172 25 50 10 01
  • Python 类型提示 Dict 语法错误 可变默认值是不允许的。使用“默认工厂”

    我不知道为什么解释器会抱怨这个类型的字典 对于这两个实例 我得到一个 不允许可变默认值 使用默认工厂 语法错误 我使用的是 python 3 7 3 from dataclasses import dataclass from typing
  • 计算另一个字符串中多个字符串的出现次数

    在 Python 2 7 中 给定以下字符串 Spot是一只棕色的狗 斑点有棕色的头发 斑点的头发是棕色的 查找字符串中 Spot brown 和 hair 总数的最佳方法是什么 在示例中 它将返回 8 我正在寻找类似的东西string c
  • 多输出堆叠回归器

    一次性问题 我正在尝试构建一个多输入堆叠回归器 添加到 sklearn 0 22 据我了解 我必须结合StackingRegressor and MultiOutputRegressor 经过多次尝试 这似乎是正确的顺序 import nu
  • NLTK 2.0分类器批量分类器方法

    当我运行此代码时 它会抛出一个错误 我认为这是由于 NLTK 3 0 中不存在batch classify 方法 我很好奇如何解决旧版本中的某些内容在新版本中消失的此类问题 def accuracy classifier gold resu
  • 我应该使用 Python 双端队列还是列表作为堆栈? [复制]

    这个问题在这里已经有答案了 我想要一个可以用作堆栈的 Python 对象 使用双端队列还是列表更好 元素数量较少还是数量较多有什么区别 您的情况可能会根据您的应用程序和具体用例而有所不同 但在一般情况下 列表非常适合堆栈 append is
  • Django Rest Framework 是否有第三方应用程序来自动生成 swagger.yaml 文件?

    我有大量的 API 端点编写在django rest framework并且不断增加和更新 如何创建和维护最新的 API 文档 我当前的版本是 Create swagger yaml文件并以某种方式在每次端点更改时自动生成 然后使用此文件作
  • 嵌套列表的重叠会产生不必要的间隙

    我有一个包含三个列表的嵌套 这些列表由 for 循环填充 并且填充由 if 条件控制 第一次迭代后 它可能类似于以下示例 a 1 2 0 0 0 0 0 0 4 5 0 0 0 0 0 0 6 7 根据条件 它们不重叠 在第二次迭代之后 新
  • 使用主题交换运行多个 Celery 任务

    我正在用 Celery 替换一些自制代码 但很难复制当前的行为 我期望的行为如下 创建新用户时 应向tasks与交换user created路由键 该消息应该触发两个 Celery 任务 即send user activate email
  • Python 3d 绘图设置固定色阶

    我正在尝试绘制两个 3d 数组 第一个数组的 z 值在范围内 0 15 0 15 第二个来自 0 001 0 001 当我绘图时 色标自动遵循数据范围 如何设置自定义比例 我不想看到 0 001 的浅色 而应该看到 0 15 的浅色 如何修
  • 矩形函数的数值傅里叶变换

    本文的目的是通过一个众所周知的分析傅里叶变换示例来正确理解 Python 或 Matlab 上的数值傅里叶变换 为此 我选择矩形函数 这里报告了它的解析表达式及其傅立叶变换https en wikipedia org wiki Rectan
  • 从 Powershell 脚本安装 Python

    当以管理员身份从 PowerShell 命令行运行以下命令时 可以在 Windows 11 上成功安装 Python c temp python 3 11 4 amd64 exe quiet InstallAllUsers 0 Instal
  • Python 3:将字符串转换为变量[重复]

    这个问题在这里已经有答案了 我正在从 txt 文件读取文本 并且需要使用我读取的数据之一作为类实例的变量 class Sports def init self players 0 location name self players pla
  • 当字段是数字时怎么说...在 mongodb 中匹配?

    所以我的结果中有一个名为 城市 的字段 结果已损坏 有时它是一个实际名称 有时它是一个数字 以下代码显示所有记录 db zips aggregate project city substr city 0 1 sort city 1 我需要修
  • Django 视图中的“请求”是什么

    在 Django 第一个应用程序的 Django 教程中 我们有 from django http import HttpResponse def index request return HttpResponse Hello world
  • 如何使用 Python 3 检查目录是否包含文件

    我到处寻找这个答案但找不到 我正在尝试编写一个脚本来搜索特定的子文件夹 然后检查它是否包含任何文件 如果包含 则写出该文件夹的路径 我已经弄清楚了子文件夹搜索部分 但检查文件却难倒了我 我发现了有关如何检查文件夹是否为空的多个建议 并且我尝
  • 带有 LSTM 的 GridSearchCV/RandomizedSearchCV

    我一直在尝试通过 RandomizedSearchCV 调整 LSTM 的超参数 我的代码如下 X train X train reshape X train shape 0 1 X train shape 1 X test X test
  • 为什么 csv.DictReader 给我一个无属性错误?

    我的 CSV 文件是 200 Service 我放入解释器的代码是 snav csv DictReader open screennavigation csv delimiter print snav fieldnames 200 for
  • python 中的“槽包装器”是什么?

    object dict 和其他地方的隐藏方法设置为这样的
  • 将索引与值交换的最快方法

    考虑pd Series s s pd Series list abcdefghij list ABCDEFGHIJ s A a B b C c D d E e F f G g H h I i J j dtype object 交换索引和值并

随机推荐

  • Java HttpUrlConnection POST 请求特殊字符奇怪的行为

    我正在尝试使用 HttpURLConnection 实现 POST 请求 这是我的代码 private static void call String body throws IOException HttpURLConnection co
  • 了解结构域突变

    来自锈书 https doc rust lang org book structs html关于如何改变结构体字段 let mut point Point x 0 y 0 point x 5 然后 可变性是绑定的属性 而不是结构本身的属性
  • 为什么 setInterval 不能避免 XSS?

    我正在经历OWASP 跨站脚本防止备忘单 https cheatsheetseries owasp org cheatsheets Cross Site Scripting Prevention Cheat Sheet html 规则 3
  • awk 查找特定日期的最大值

    我有一个包含多行的文件 每行包含以下数据 name 20150801 1 20150802 4 20150803 6 20150804 7 20150805 7 20150806 8 20150807 11532 20150808 1239
  • 如何让java日历从星期一开始工作日?

    我已经编写了代码 它使用 Java 日历并显示时间戳中的 DAY OF WEEK 但默认日历从星期日 1 开始 我希望从星期一开始 例如 星期一应该返回 1 这是我的代码 Calender c Calender getInstance Ti
  • 是否存在从 Eclipse 中的同一代码库维护免费和专业应用程序版本的约定?

    我正在发布一个应用程序的两个版本 免费和付费 两者之间的差异很少 我想使用相同的代码库来发布两者 也许为其他版本定义了不同的常量 有人这样做过吗 有人能指出我正确的方向吗 谢谢 Use an Android 库项目 http develop
  • React 的 setState 方法带有 prevState 参数

    我是 React 新手 只是对 setState 方法有疑问 假设我们有一个组件 class MyApp extends React Component state count 3 Increment gt this setState pr
  • 使用 jQuery 文件上传 - blueimp(基于 Ajax)php / yii 上传超过 1GB 到 2GB 的大文件,它在 Firefox 浏览器中显示错误

    我正在尝试上传一个大文件1GB to 2GB using jQuery File Upload blueimp 基于阿贾克斯 php yii Framework 1 15我已设置这些值来上传更大的文件 memory limit 2048M
  • .NET Linq 左连接

    我在 SQL 中有 2 个表 Table 1 Step Id Step Name Table 2 Profile Id Step Id Completed 即使表 2 中不匹配 我也想返回以下结果 Results Table1 Step I
  • Python + SqlAlchemy:当父子都是新建时添加父子记录

    我问过一个类似的问题 https stackoverflow com q 59097167 2144390已经 但我认为如果我不提供我已经编码的示例 而是简单地陈述我的案例的目标 那么会更清楚 开始 我有一个处于自引用一对多关系的表 即 它
  • 使用字符串输入和输出运行进程

    这里有很多与 fork 和 exec 相关的问题 不过 我还没有找到真正使使用它们的过程变得简单的方法 而让程序员的生活变得简单就是目标 我需要一个 C Linux 友好的函数来执行以下操作 string RunCommand string
  • 如何给函数起别名?

    我正在尝试为 R 中的函数创建别名 例如 要获取 R 中向量的长度 length the vector returns the length of the vector 我想创建一个名为 len 的函数的别名 len the vector
  • 使用 Serde 反序列化具有多种类型字段的 JSON

    我有一些 JSON 文本数据 其字段可以是字符串或字符串数 组 以下是四个可能的示例 keya some string keyb some string keya some string keyb some string some stri
  • 比较 SPARQL 图

    如何使用 SPARQL 比较两个 RDF 图 如果我有图表 a 和 b 我想找到 a 出现在 b 中的所有时间 我可以查询 a 的所有主语 谓词和宾语 然后以编程方式构建一个与 b 中的 a 模式匹配的模式查询 有没有一种方法可以在 SPA
  • xcode 命令行测试,参数在启动时传递

    我在 CI 上实施 xcodebuild 命令测试时遇到了小问题 我有与特定设备语言相关的测试 在 xcode 中我可以将 启动时传递的参数 设置为 AppleLanguages 语言 我可以使用 xcodebuild 传递该参数吗 我的脚
  • 如何用C++封装视频文件的H.264码流

    我正在尝试转换视频文件 mp4 到 Dicom 文件 我通过在 Dicom 中存储单个图像 视频的每帧一个图像 成功地做到了这一点 但结果是文件太大 这对我来说不好 相反 我想将存储在视频文件中的 H 264 比特流封装到 Dicom 文件
  • 将方法的名称作为参数传递

    private void Method1 Do something Log Something Method1 private void Method2 Do something Log Something Method2 private
  • 我什么时候应该使用 ConcurrentDictionary 和 Dictionary?

    我总是很困惑该选择哪一个 据我所知 我使用Dictionary over List如果我想要两种数据类型Key and Value所以我可以很容易地找到一个值key但我总是很困惑是否应该使用ConcurrentDictionary or D
  • 如何在 php curl 中设置 PHP_AUTH_PW

    如何在phpcurl中设置PHP AUTH PW和PHP AUTH USER参数 在服务器端检查 if isset SERVER PHP AUTH PW 打印 授权错误 任何帮助 将不胜感激 Thanks 它称为 basic auth 适用
  • 命令链的别名

    我有一个tool使用命令 step1 step2 and step3 我可以通过调用以下方式链接它们 tool step1 step2 step3 我想要一个名为all通过调用以下命令来运行所有步骤 tool all 我找到了一个可行的解决