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

Optional CLI arguments with python Click library option

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

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

  1. $ myscript ⇒ 选项 = False

  2. $ myscript -o ⇒ 选项 = True

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

此外,我希望选项为 "eager"(例如,在 "Click" 术语中,在回调后中止执行)​​,但现在可以忽略此选项。


当我这样定义我的参数时:

@click.command()
@click...
@click.option("-o", "option", is_flag=True, default=False)
def myscript(..., option):

我实现了例子1和2,但是3自然是不可能的,因为flag只检测到present/not present。


当我这样定义我的参数时:

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

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


这看起来不像是一个超出这个世界的场景,但我似乎无法实现这个或找到这样的例子。

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

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

@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)

稍后编辑 使用一个选项,我设法通过向命令定义添加一个参数来实现这一点。

@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)

如果您只希望后面最多有一个参数,则可以删除 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)

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