5

这个问题是关于点击包的:

Click 是一个 Python 包,用于以可组合的方式使用尽可能少的代码创建漂亮的命令行界面。它是“命令行界面创建工具包”。它是高度可配置的,但带有开箱即用的合理默认值。

它旨在使编写命令行工具的过程变得快速而有趣,同时还防止因无法实现预期的 CLI API 而导致的任何挫败感。

我想click.Option在 my中添加一个click.Command,这会改变该命令的其他参数的行为。考虑以下示例:

@click.option('--x', default=42, prompt=True)
@click.command
def cli_a(x):
  print(x)


@click.option('--x', default=42, prompt=False)
@click.command
def cli_b(x):
  print(x)

如果cli_a在没有明确指定x的情况下调用,则会提示用户提供一个值(或使用 ENTER 确认默认值)。如果cli_b在不指定x默认值的情况下调用,则在不提示用户的情况下使用。

我现在想添加一个标志click.Option,允许用户在上述变体之一之间进行选择(在运行时)。因此,调用cli_c --i的行为类似于cli_a,调用cli_c的行为类似于cli_b.

@click.option('--i', is_flag=True, default=False, expose_value=False)
@click.option('--x', default=42, prompt=False)
@click.command
def cli_c(x):
  print(x)

这对当前的 API 可行吗?可行吗?

类似的用例类似于anwser-all-confimation-prompts-with-yes标志。通常,如果 cli 工具应该由用户交互使用,并且通过脚本或类似的东西在自动化模式下使用,通常会出现这种情况。

4

1 回答 1

6

我想出了以下代码,它会产生所需的行为:

def deactivate_prompts(ctx, param, value):
    if not value:
        click.echo("entering batch mode, deactivating all prompts ...")
        for p in ctx.command.params:
            if isinstance(p, click.Option) and p.prompt is not None:
                p.prompt = None
    return value

@click.option('--i/--b', default=True, is_eager=True, expose_value=False, callback=deactivate_prompts)
@click.option('--x', default=42, prompt=True)
@click.command
def cli_c(x):
  print(x)

这个想法是使用急切选项的回调来修改所有(其他)Options.Command

潜在的弱点:

  • 这是一个全有或全无的解决方案,即所有提示都处于活动状态或没有。对于我的用例,这正是我想要的,但对于其他情况可能并非如此。
  • 这只适用于一个方向,即关闭提示。因此,每个Option可能显示或不显示提示的内容都必须配置为好像显示提示一样。
  • 如果我们关闭提示,我们仍然需要一个 value Option,所以备用 value-source 是必须的。即必须提供默认值。
于 2015-09-21T15:15:13.503 回答