Python Click 多个组名

4

在Python Click中,是否可以像这样做?我想要为同一个click.Group使用不同的名称。

import click

class CustomMultiGroup(click.Group):

    def group(self, *args, **kwargs):
        """Behaves the same as `click.Group.group()` except if passed
        a list of names, all after the first will be aliases for the first.
        """
        def decorator(f):
            if isinstance(args[0], list):
                _args = [args[0][0]] + list(args[1:])
                for alias in args[0][1:]:
                    cmd = super(CustomMultiCommand, self).group(
                        alias, *args[1:], **kwargs)(f)
                    cmd.short_help = "Alias for '{}'".format(_args[0])
            else:
                _args = args
            cmd = super(CustomMultiCommand, self).group(
                *_args, **kwargs)(f)
            return cmd

        return decorator

@click.group(cls=CustomMultiGroup)
def mycli():
    pass

@cli.group(['my-group', 'my-grp'])
def my_group():
    pass

@my_group.command()
def my_command():
    pass

我希望我的命令行看起来像这样:

mycli my-group my-command

并且。
mycli my-grp my-command

但是引用同一函数。

这篇文章参考了Python Click 多个命令名称


Click 有别名的概念吗? - Laurent LAPORTE
1
请查看命令别名 - Laurent LAPORTE
更像是这样的 https://dev59.com/7aXja4cB1Zd3GeqPWsx8 - Élie Deloumeau-Prigent
该组本身不会从命令行中被调用。通常只有在它本身位于另一个组内时,才需要调用该组。因此,为了使您的第一行代码有用,它需要是另一个组的成员。因此,它不应该是 @click.group(),而应该是 @my_outer_group.group(),其中 my_outer_group 是先前声明的组。您能确认这是正确的吗? - Stephen Rauch
这不是现实情况,但它可能会发生。我很快会测试它。 - Élie Deloumeau-Prigent
Stephen Rauch,我已经编辑了我的消息并附上了我的测试。 - Élie Deloumeau-Prigent
2个回答

2
使用以下包之一是在Click中拥有命令别名的最简单方法: 免责声明:我是Cloup的作者。
这两种实现略有不同。
  • Cloup将命令的别名存储在命令本身中。这使得Cloup能够在命令本身的--help中记录命令的别名。

  • click-aliases始终在组的“Commands”部分中显示(子)命令的别名。在Cloup中,您可以根据自己的喜好启用/禁用此行为(默认情况下,不会显示别名)。


2

click.Groupclick.Command的行为不同,因此您需要修改示例以允许别名组访问已别名化的组的命令:

自定义类

该类覆盖了click.Group.group()方法,该方法用于装饰组函数。它添加了传递组别名列表的功能。此类还添加了一个简短的帮助,引用了别名组。

import click

class CustomMultiGroup(click.Group):

    def group(self, *args, **kwargs):
        """Behaves the same as `click.Group.group()` except if passed
        a list of names, all after the first will be aliases for the first.
        """
        def decorator(f):
            aliased_group = []
            if isinstance(args[0], list):
                # we have a list so create group aliases
                _args = [args[0][0]] + list(args[1:])
                for alias in args[0][1:]:
                    grp = super(CustomMultiGroup, self).group(
                        alias, *args[1:], **kwargs)(f)
                    grp.short_help = "Alias for '{}'".format(_args[0])
                    aliased_group.append(grp)
            else:
                _args = args

            # create the main group
            grp = super(CustomMultiGroup, self).group(*_args, **kwargs)(f)

            # for all of the aliased groups, share the main group commands
            for aliased in aliased_group:
                aliased.commands = grp.commands

            return grp

        return decorator

测试代码:

@click.group(cls=CustomMultiGroup)
def cli():
    pass

@cli.group(['my-group', 'my-grp'])
def my_group():
    """ My Sub Command """
    pass

@my_group.command('my-command')
def my_command():
    click.echo("My Command")

cli('--help'.split())
cli('my-grp --help'.split())
cli('my-group --help'.split())
cli('my-grp my-command'.split())
cli('my-group my-command'.split())

测试结果:

Usage: my_cli [OPTIONS] COMMAND [ARGS]...

Options:
  --help  Show this message and exit.

Commands:
  my-group  My Sub Command
  my-grp    Alias for 'my-group'

Process finished with exit code 0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接