同时单击具有选项和命令的组
Click group with options and commands at the same time
我正在尝试创建具有以下行为的应用程序:
myapp
- 将启动应用程序并执行 A
myapp "some argument"
- 会做 B 事。B 事受参数 "some argument".
的影响
myapp command
- 将启动具有功能 C 的 "command"(由装饰器 @cli.command
表示)。这将受到 click 必须提供的所有内容的影响,例如 @click.option
.
注意,在我的应用程序中会有 更多命令 像 C.
我已尝试使用以下代码实现:
import click
class GroupWithOption(click.Group):
def list_commands(self, ctx):
return ['command']
def get_command(self, ctx, cmd_name):
if cmd_name == 'command':
return command
else:
return do_b
@click.group(cls=GroupWithOption, invoke_without_command=True)
def main():
print("Does A")
@main.command()
def command():
print("Does C")
@main.command()
def do_b():
print("Does B")
if __name__ == '__main__':
main()
结果喜忧参半。首先,我可以很容易地调用 3 种不同的行为(或更多),但我无法弄清楚如何将参数传递给 B 命令。 我不喜欢这个解决方案。它似乎不是一个干净的解决方案。为了正常运行,它需要使用全局变量和一些讨厌的技巧。
你们知道更好的方法吗?如何完成这个?
一种方法是结合给出的两个答案 :
关键要素:
@click.group(cls=DefaultCommandGroup, invoke_without_command=True)
@click.pass_context
def main(ctx):
if not ctx.invoked_subcommand:
click.echo("Does A")
@main.command(default_command=True)
@click.argument('args', nargs=-1)
def default_cmd_with_args(args):
click.echo("Does B: {}".format(args))
这是如何工作的?
if not ctx.invoked_subcommand:
允许仅在 "no command" 情况下调用组命令,并且
@click.group(cls=DefaultCommandGroup, invoke_without_command=True)
结合:
@main.command(default_command=True)
如果找不到其他命令,则允许命令为 运行。
测试代码:
import click
@click.group(cls=DefaultCommandGroup, invoke_without_command=True)
@click.pass_context
def main(ctx):
"""My Great CLI"""
if not ctx.invoked_subcommand:
click.echo("Does A")
@main.command(default_command=True)
@click.argument('args', nargs=-1)
def default_cmd_with_args(args):
"""Command run without a command"""
click.echo("Does B: {}".format(args))
@main.command()
def cmd_c1():
"""A c1 command"""
click.echo("Does C1")
@main.command()
def cmd_c2():
"""A c2 command"""
click.echo("Does C2")
if __name__ == "__main__":
commands = (
'',
'random args',
'cmd_c1',
'cmd_c2',
'--help',
)
import sys, time
time.sleep(1)
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
for command in commands:
try:
time.sleep(0.1)
print('-----------')
print('> ' + command)
time.sleep(0.1)
main(command.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
结果:
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
>
Does A
-----------
> random args
Does B: ('random', 'args')
-----------
> cmd_c1
Does C1
-----------
> cmd_c2
Does C2
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...
My Great CLI
Options:
--help Show this message and exit.
Commands:
<> Command run without a command
cmd_c1 A c1 command
cmd_c2 A c2 command
我正在尝试创建具有以下行为的应用程序:
myapp
- 将启动应用程序并执行 A
myapp "some argument"
- 会做 B 事。B 事受参数 "some argument".
myapp command
- 将启动具有功能 C 的 "command"(由装饰器 @cli.command
表示)。这将受到 click 必须提供的所有内容的影响,例如 @click.option
.
注意,在我的应用程序中会有 更多命令 像 C.
我已尝试使用以下代码实现:
import click
class GroupWithOption(click.Group):
def list_commands(self, ctx):
return ['command']
def get_command(self, ctx, cmd_name):
if cmd_name == 'command':
return command
else:
return do_b
@click.group(cls=GroupWithOption, invoke_without_command=True)
def main():
print("Does A")
@main.command()
def command():
print("Does C")
@main.command()
def do_b():
print("Does B")
if __name__ == '__main__':
main()
结果喜忧参半。首先,我可以很容易地调用 3 种不同的行为(或更多),但我无法弄清楚如何将参数传递给 B 命令。 我不喜欢这个解决方案。它似乎不是一个干净的解决方案。为了正常运行,它需要使用全局变量和一些讨厌的技巧。
你们知道更好的方法吗?如何完成这个?
一种方法是结合给出的两个答案
关键要素:
@click.group(cls=DefaultCommandGroup, invoke_without_command=True)
@click.pass_context
def main(ctx):
if not ctx.invoked_subcommand:
click.echo("Does A")
@main.command(default_command=True)
@click.argument('args', nargs=-1)
def default_cmd_with_args(args):
click.echo("Does B: {}".format(args))
这是如何工作的?
if not ctx.invoked_subcommand:
允许仅在 "no command" 情况下调用组命令,并且
@click.group(cls=DefaultCommandGroup, invoke_without_command=True)
结合:
@main.command(default_command=True)
如果找不到其他命令,则允许命令为 运行。
测试代码:
import click
@click.group(cls=DefaultCommandGroup, invoke_without_command=True)
@click.pass_context
def main(ctx):
"""My Great CLI"""
if not ctx.invoked_subcommand:
click.echo("Does A")
@main.command(default_command=True)
@click.argument('args', nargs=-1)
def default_cmd_with_args(args):
"""Command run without a command"""
click.echo("Does B: {}".format(args))
@main.command()
def cmd_c1():
"""A c1 command"""
click.echo("Does C1")
@main.command()
def cmd_c2():
"""A c2 command"""
click.echo("Does C2")
if __name__ == "__main__":
commands = (
'',
'random args',
'cmd_c1',
'cmd_c2',
'--help',
)
import sys, time
time.sleep(1)
print('Click Version: {}'.format(click.__version__))
print('Python Version: {}'.format(sys.version))
for command in commands:
try:
time.sleep(0.1)
print('-----------')
print('> ' + command)
time.sleep(0.1)
main(command.split())
except BaseException as exc:
if str(exc) != '0' and \
not isinstance(exc, (click.ClickException, SystemExit)):
raise
结果:
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
>
Does A
-----------
> random args
Does B: ('random', 'args')
-----------
> cmd_c1
Does C1
-----------
> cmd_c2
Does C2
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...
My Great CLI
Options:
--help Show this message and exit.
Commands:
<> Command run without a command
cmd_c1 A c1 command
cmd_c2 A c2 command