python-click:添加修改其他参数行为的选项

Pet*_*erE 5 python command-line-interface python-click

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

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

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

我想将 a 添加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)
Run Code Online (Sandbox Code Playgroud)

如果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)
Run Code Online (Sandbox Code Playgroud)

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

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

Pet*_*erE 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)
Run Code Online (Sandbox Code Playgroud)

我们的想法是使用一个热心选项的回调修改所有(其他)OptionsCommand

潜在的弱点:

  • 这是一个全有或全无的解决方案,即所有提示都处于活动状态或没有。对于我的用例,这正是我想要的,但对于其他用例可能并非如此。
  • 这仅适用于一个方向,即通过关闭提示。因此,每个Option可能会或可能不会显示提示的都必须配置为显示提示。
  • 如果我们关闭提示,我们仍然需要一个值Option,因此必须有一个替代值源。即必须提供默认值。