带有 python 单击库选项的可选 CLI 参数

kon*_*tur 6 python click command-line-interface

在解析某些 CLI 选项时,我遇到了 Python Click库的难题。

我想要一个单独充当标志的选项,但可以选择接受字符串值。例如:

  1. $ myscript? 选项 = 错误

  2. $ myscript -o? 选项 = 真

  3. $ myscript -o foobar? 选项 = Foobar

此外,我希望该选项为“急切”(例如,在“单击”术语中,回调后中止执行)​​,但现在可以忽略此选项。


当我这样定义我的论点时:

@click.command()
@click...
@click.option("-o", "option", is_flag=True, default=False)
def myscript(..., option):
Run Code Online (Sandbox Code Playgroud)

我实现了示例 1 和 2,但 3 自然是不可能的,因为该标志仅检测存在/不存在。


当我这样定义我的论点时:

@click.command()
@click...
@click.option("-o", "--option", default="") # Let's assume I will cast empty string to False
def myscript(..., option):
Run Code Online (Sandbox Code Playgroud)

我实现了 1 和 3,但是 2 将失败并显示Error: -c option requires an argument.


这似乎不像是一个超凡脱俗的场景,但我似乎无法实现这一目标或找到表现如此的示例。

我如何定义一个@click.option被解析为:

  • False 未设置时
  • True 设置但没有值时
  • str 当用值设置时

aft*_*ner 4

我设法实现此行为的一种方法是实际使用如下参数。我会将其作为解决方法发布,同时尝试查看是否可以通过选项来完成,并且我将相应地更新我的帖子

@click.command(context_settings={"ignore_unknown_options": True})
@click.argument("options", nargs=-1)
def myscript(options):
    option = False
    if options is ():
        option = False
    if '-o' in options or '--option' in options:
        option = True
    if len(options) > 1:
        option = options[1]
    print(option)
Run Code Online (Sandbox Code Playgroud)

稍后编辑 使用选项,我通过向命令定义添加参数来成功实现此目的。

@click.command()
@click.option('-o', '--option', is_flag=True, default=False, is_eager=True)
@click.argument('value', nargs=-1)
def myscript(option, value):
    if option and value != ():
        option = value[0]
    print(option)

Run Code Online (Sandbox Code Playgroud)

如果您只期望最多跟随一个参数,则可以将其nargs删除,并且可以将其视为不需要。

@click.command()
@click.option('-o', '--option', is_flag=True, default=False, is_eager=True)
@click.argument('value', required=False)
def myscript(option, value=None):
    if option and value is not None:
        option = value
    print(option)
Run Code Online (Sandbox Code Playgroud)

也可以通过将上下文生成器放在一起并存储一些状态来实现,但这似乎是最不理想的解决方案,因为您将依赖于存储状态的上下文。