python-click: 添加修改其他参数行为的选项
python-click: Adding an option that modifies the behavior of other parameters
这个问题是关于 click 包的:
Click is a Python package for creating beautiful command line
interfaces in a composable way with as little code as necessary. It’s
the “Command Line Interface Creation Kit”. It’s highly configurable
but comes with sensible defaults out of the box.
It aims to make the process of writing command line tools quick and
fun while also preventing any frustration caused by the inability to
implement an intended CLI API.
我想将 click.Option
添加到我的 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)
如果在未明确指定 x
的情况下调用 cli_a
,系统会提示用户提供一个值(或使用 ENTER 确认默认值)。如果在未指定 x
的情况下调用 cli_b
,则使用默认值而不提示用户。
我现在想添加一个标志 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 工具应该可以由用户交互使用,并且可以通过脚本或类似的东西在自动模式下使用,通常会出现这种情况。
我想出了以下代码,它产生了所需的行为:
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)
想法是使用急切选项的回调来修改 Command
的所有(其他)Options
。
潜在弱点:
- 这是一个全有或全无的解决方案,即要么所有提示都处于活动状态,要么 none。对于我的用例,这正是我想要的,但对于其他情况可能并非如此。
- 这只能在一个方向上起作用,即关闭提示。因此,每个可能显示或不显示提示的
Option
都必须配置为显示提示。
- 如果我们关闭提示,我们仍然需要一个值
Option
,因此必须使用备用值源。 IE。必须提供默认值。
这个问题是关于 click 包的:
Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It’s the “Command Line Interface Creation Kit”. It’s highly configurable but comes with sensible defaults out of the box.
It aims to make the process of writing command line tools quick and fun while also preventing any frustration caused by the inability to implement an intended CLI API.
我想将 click.Option
添加到我的 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)
如果在未明确指定 x
的情况下调用 cli_a
,系统会提示用户提供一个值(或使用 ENTER 确认默认值)。如果在未指定 x
的情况下调用 cli_b
,则使用默认值而不提示用户。
我现在想添加一个标志 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 工具应该可以由用户交互使用,并且可以通过脚本或类似的东西在自动模式下使用,通常会出现这种情况。
我想出了以下代码,它产生了所需的行为:
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)
想法是使用急切选项的回调来修改 Command
的所有(其他)Options
。
潜在弱点:
- 这是一个全有或全无的解决方案,即要么所有提示都处于活动状态,要么 none。对于我的用例,这正是我想要的,但对于其他情况可能并非如此。
- 这只能在一个方向上起作用,即关闭提示。因此,每个可能显示或不显示提示的
Option
都必须配置为显示提示。 - 如果我们关闭提示,我们仍然需要一个值
Option
,因此必须使用备用值源。 IE。必须提供默认值。