Python 单击多个命令名称
Python Click multiple command names
是否可以通过 Python Click 执行类似的操作?
@click.command(name=['my-command', 'my-cmd'])
def my_command():
pass
我希望我的命令行是这样的:
mycli my-command
和
mycli my-cmd
但引用相同的函数。
我需要像 AliasedGroup 这样的 class 吗?
AliasedGroup 不是您想要的,因为它允许最短的前缀匹配,而且您似乎需要实际的别名。但该示例确实提供了可行方向的提示。它继承自 click.Group
并覆盖了一些行为。
这是一种实现您所追求的目标的方法:
自定义Class
此 class 覆盖了用于修饰命令函数的 click.Group.command()
方法。它增加了传递命令别名列表的能力。此 class 还添加了一个简短的帮助,其中引用了别名命令。
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
使用自定义 Class
通过将 cls
参数传递给 click.group()
装饰器,任何通过 group.command()
添加到组中的命令都可以传递一个命令名称列表。
@click.group(cls=CustomMultiCommand)
def cli():
"""My Excellent CLI"""
@cli.command(['my-command', 'my-cmd'])
def my_command():
....
测试代码:
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())
测试结果:
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
这里有一个更简单的方法来解决同样的问题:
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,
}
既然有人问了这个问题,就创建了一个click-aliases
library。
它的工作方式有点像其他答案,只是您不必自己声明命令 class:
import click
from click_aliases import ClickAliasedGroup
@click.group(cls=ClickAliasedGroup)
def cli():
pass
@cli.command(aliases=['my-cmd'])
def my_command():
pass
是否可以通过 Python Click 执行类似的操作?
@click.command(name=['my-command', 'my-cmd'])
def my_command():
pass
我希望我的命令行是这样的:
mycli my-command
和
mycli my-cmd
但引用相同的函数。
我需要像 AliasedGroup 这样的 class 吗?
AliasedGroup 不是您想要的,因为它允许最短的前缀匹配,而且您似乎需要实际的别名。但该示例确实提供了可行方向的提示。它继承自 click.Group
并覆盖了一些行为。
这是一种实现您所追求的目标的方法:
自定义Class
此 class 覆盖了用于修饰命令函数的 click.Group.command()
方法。它增加了传递命令别名列表的能力。此 class 还添加了一个简短的帮助,其中引用了别名命令。
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
使用自定义 Class
通过将 cls
参数传递给 click.group()
装饰器,任何通过 group.command()
添加到组中的命令都可以传递一个命令名称列表。
@click.group(cls=CustomMultiCommand)
def cli():
"""My Excellent CLI"""
@cli.command(['my-command', 'my-cmd'])
def my_command():
....
测试代码:
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())
测试结果:
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
这里有一个更简单的方法来解决同样的问题:
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,
}
既然有人问了这个问题,就创建了一个click-aliases
library。
它的工作方式有点像其他答案,只是您不必自己声明命令 class:
import click
from click_aliases import ClickAliasedGroup
@click.group(cls=ClickAliasedGroup)
def cli():
pass
@cli.command(aliases=['my-cmd'])
def my_command():
pass