如何为多个命令定义常用的 python-click 选项?

How to define common python-click options for multiple commands?

在python 3.8中我想定义一些对多个命令通用的点击选项。我尝试了以下代码:

import click


@click.group()
@click.option(
    "-v",
    "--verbose",
    count=True,
    default=0,
    help="-v for DEBUG",
)
@click.option(
    "--path",
    help="Main Path.",
)
def cli():
  pass


@click.command("list")
@click.option(
    "--list-option",
    help="Special option for list command.",
)
def my_list_command(verbose, path, list_option):
    print(verbose, path, list_option)

@click.command("find")
@click.option(
    "--find-option",
    help="Special option for find command.",
)
def my_find_command(verbose, path, find_option):
    print(verbose, path, find_option)

cli.add_command(my_list_command)
cli.add_command(my_find_command)

if __name__ == '__main__':
    cli()

但是当我尝试 运行 命令时

python script.py list

我收到一个错误

TypeError: cli() got an unexpected keyword argument 'verbose'

我想要的是命令 list 具有以下三个选项:verbosepathlist-option 以及命令 find有以下三个选项:verbosepathfind-option。我不想为 verbosepath 定义选项两次。

有办法吗?

我也尝试过使用 @click.pass_context 但这似乎并没有解决问题。

您当前定义它的方式将起作用,但 --verbose 选项属于主命令组,因此您需要将其称为 python script.py --verbose list(和 my_find_commandmy_list_command 不会将其作为参数接收,只有 cli).

要在多个命令中使用相同的选项而不会重复太多,您可以将它分配给一个变量,然后使用它两次:

verbose_option = click.option(
    "-v",
    "--verbose",
    count=True,
    default=0,
    help="-v for DEBUG",
)

...

@click.command()
@verbose_option
def foo(verbose):
    ...

@click.command()
@verbose_option
def bar(verbose):
    ...

不相关,但我们正在讨论:有一种更简单的命令分组方法,无需执行 cli.add_command(my_find_command):只需使用 @cli.command() 而不是 @click.command()

import click

option_verbose = click.option(
    "-v",
    "--verbose",
    count=True,
    default=0,
    help="-v for DEBUG",
)

@click.group()
def cli():
    pass


@cli.command("list")
@option_verbose
@click.option(
    "--list-option",
    help="Special option for list command.",
)
def my_list_command(verbose, list_option):
    print(verbose, list_option)

@cli.command("find")
@option_verbose
@click.option(
    "--find-option",
    help="Special option for find command.",
)
def my_find_command(verbose, list_option):
    print(verbose, list_option)

if __name__ == '__main__':
    cli()