如何设置python的click参数来别名不同的参数从选项回调?

gijlo24d  于 2023-10-21  发布在  Python
关注(0)|答案(1)|浏览(108)

有许多实用程序都有一个选项可以作为其他实用程序的别名,如下所示:

$ python3 ./1.py --help
Usage: 1.py [OPTIONS]

Options:
  --format TEXT
  --long TEXT    Alias to --format=long_format
  --help         Show this message and exit.

我如何在单击中实现--long选项,以便单击时自动设置--long=long_format选项在一个简单的事情?
我最终使用了一个全局变量来覆盖本地参数:

import argparse
from typing import Any, Optional

import click

PARAMS = {}

def set_param(
    opt: str, val: Any, ctx: click.Context, param: Optional[click.Parameter], value: Any
):
    if value:
        PARAMS[opt] = val

@click.command()
@click.option("--format", default="default_format")
@click.option(
    "--long",
    is_flag=True,
    help="Alias to --format=long_format",
    callback=lambda *args: set_param("format", "long_format", *args),
)
def cli(**kwargs):
    args = argparse.Namespace(**{**kwargs, **PARAMS})
    print(args.format)

cli()

但是在@click.option(callback=<here>)内部已经有ctx可用。我试着设置ctx.params["format"] = "long_format",但它不工作。有没有更好的方法来设置@click.option别名自动设置不同的选项?我试着阅读单击源代码和文档,但没有找到任何相关的东西。
换句话说,如何实现以下@click.option回调:

import argparse
from typing import Any, Optional
import click    

@click.command()
@click.option("--format", default="default_format")
@click.option(
    "--long",
    is_flag=True,
    help="Alias to --format=long_format",
    callback=lambda *args: "How to set --format=long_format from here?",
)
def cli(**kwargs):
    args = argparse.Namespace(**{**kwargs, **PARAMS})
    print(args.format)

cli()

基于下面的惊人答案,我创建了这个:

def __alias_option_callback(
    aliased: Dict[str, Any],
    ctx: click.Context,
    param: click.Parameter,
    value: Any,
):
    """Callback called from alias_option option."""
    if value:
        for paramname, val in aliased.items():
            param = next(p for p in ctx.command.params if p.name == paramname)
            param.default = val

def alias_option(
    *param_decls: str,
    aliased: Dict[str, Any],
    **attrs: Any,
):
    """Add this to click options to have an alias for other options"""
    aliasedhelp = " ".join(
        "--"
        + k.replace("_", "-")
        + ("" if v is True else f"={v}" if isinstance(v, int) else f"={v!r}")
        for k, v in aliased.items()
    )
    return click.option(
        *param_decls,
        is_flag=True,
        help=f"Alias to {aliasedhelp}",
        callback=lambda *args: __alias_option_callback(aliased, *args),
        **attrs,
    )

@click.command()
# Auto generates help= and sets --format when used.
@alias_option("--long", aliased=dict(format="long_format"))
def cli():
   pass

它并不完美,因为它不能正确地处理False,但适用于我有限的用例。

5kgi1eie

5kgi1eie1#

IIUC中,您可以以图解方式设置--format选项的默认值:

import argparse
from typing import Any, Optional

import click

def set_long(ctx, *_):
    for p in ctx.command.params:
        if p.name == "format":
            p.default = "long_format"

@click.command()
@click.option("--format", default="default_format")
@click.option(
    "--long", is_flag=True, help="Alias to --format=long_format", callback=set_long
)
def cli(**kwargs):
    args = argparse.Namespace(**kwargs)
    print(args.format)

cli()

打印python3 script.py --long将打印:

long_format

相关问题