Python单击多个命令名称

Éli*_*ent 3 python alias command python-click

是否可以使用Python Click执行类似的操作?

@click.command(name=['my-command', 'my-cmd'])
def my_command():
    pass
Run Code Online (Sandbox Code Playgroud)

我希望命令行如下所示:

mycli my-command
Run Code Online (Sandbox Code Playgroud)

mycli my-cmd 
Run Code Online (Sandbox Code Playgroud)

但引用相同的功能。

我需要像AliasedGroup这样的课程吗?

Dev*_*wal 9

这是解决相同问题的更简单方法:

class AliasedGroup(click.Group):
    def get_command(self, ctx, cmd_name):
        try:
            cmd_name = ALIASES[cmd_name].name
        except KeyError:
            pass
        return super().get_command(ctx, cmd_name)


@click.command(cls=AliasedGroup)
def cli():
    ...

@click.command()
def install():
    ...

@click.command()
def remove():
    ....


cli.add_command(install)
cli.add_command(remove)


ALIASES = {
    "it": install,
    "rm": remove,
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*uch 5

AliasedGroup不是您想要的,因为它允许最短的前缀匹配,并且看来您需要实际的别名。但是该示例确实提供了可行方向的提示。它继承click.Group并覆盖了某些行为。

这是一种接近您所追求的方式:

自定义类

该类覆盖了click.Group.command()用于装饰命令功能的方法。它增加了传递命令别名列表的功能。此类还添加了一个简短的帮助,其中引用了别名命令。

class CustomMultiCommand(click.Group):

    def command(self, *args, **kwargs):
        """Behaves the same as `click.Group.command()` 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).command(
                        alias, *args[1:], **kwargs)(f)
                    cmd.short_help = "Alias for '{}'".format(_args[0])
            else:
                _args = args
            cmd = super(CustomMultiCommand, self).command(
                *_args, **kwargs)(f)
            return cmd

        return decorator
Run Code Online (Sandbox Code Playgroud)

使用自定义类

通过将cls参数传递给click.group()装饰器,group.command()可以将通过命令行添加到组的任何命令传递给命令名称列表。

@click.group(cls=CustomMultiCommand)
def cli():
    """My Excellent CLI"""

@cli.command(['my-command', 'my-cmd'])
def my_command():
    ....
Run Code Online (Sandbox Code Playgroud)

测试代码:

import click

@click.group(cls=CustomMultiCommand)
def cli():
    """My Excellent CLI"""


@cli.command(['my-command', 'my-cmd'])
def my_command():
    """This is my command"""
    print('Running the command')


if __name__ == '__main__':
    cli('--help'.split())
Run Code Online (Sandbox Code Playgroud)

检测结果:

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

  My Excellent CLI

Options:
  --help  Show this message and exit.

Commands:
  my-cmd      Alias for 'my-command'
  my-command  This is my command
Run Code Online (Sandbox Code Playgroud)


bfo*_*ine 3

自从提出这个问题以来,有人(不是我)创建了一个click-aliases

\n

它的工作方式有点类似于其他答案,只是您不必自己声明命令类:

\n
import click\nfrom click_aliases import ClickAliasedGroup\n\n@click.group(cls=ClickAliasedGroup)\ndef cli():\n    pass\n\n@cli.command(aliases=[\'my-cmd\'])\ndef my_command():\n    pass\n
Run Code Online (Sandbox Code Playgroud)\n