Python 在多个顶级命令之间共享子命令

Python 在多个顶级命令之间共享子命令,python,command-line-interface,python-click,Python,Command Line Interface,Python Click,我有一个Python项目,有多个顶级入口点,让我们称它们为foo和bar。两个入口点使用相同的代码库,我希望使用实现version()命令的完全相同的代码来实现foo version和bar version命令 所以,在foo.py中,我会说 import click @click.group() def foo(): @foo.command @option('--long', ...) @option('--check', ...) def version(long, check):

我有一个Python项目,有多个顶级入口点,让我们称它们为
foo
bar
。两个入口点使用相同的代码库,我希望使用实现
version()
命令的完全相同的代码来实现
foo version
bar version
命令

所以,在foo.py中,我会说

import click

@click.group()
def foo():

@foo.command
@option('--long', ...)
@option('--check', ...)
def version(long, check):
    ...
栏中相同
。如何避免在两个文件中重复命令定义?

参考,您可以构建一个单击命令,并将其作为两个单独的操作添加到多个组或命令中

生成单击命令: 首先,我们需要构建一个click命令。我们将使用一个helper函数来修饰importable命令,如下所示:

import click

def importable_command(*args, **kwargs):
    def decorator(f):
        return click.decorators.command(*args, **kwargs)(f)
    return decorator


@importable_command('version')
@click.option('--long')
@click.option('--check')
def version_cmd(long, check):
    click.echo('version long: {}'.format(long))
    click.echo('version check: {}'.format(check))
将命令添加到组: 然后,我们可以导入该命令并将其添加到具有以下内容的组:

from where-ever-we-defined-it import version_cmd

# Add our version command to this group
a_group.add_command(version_cmd)
测试代码: 结果:
很酷。非常感谢。不知怎么的,我总是被装潢师的魔法弄得心神不宁。我在使它发挥作用方面遇到了一些困难。我不断得到:文件“/build/snaprr\u infra/common\u cli.py”,第40行,共有。add\u命令(autoupgrade\u cmd)文件“/usr/local/lib/python3.6/dist-packages/click/core.py”,第1221行,在add\u-command-name=name或cmd.name-AttributeError中:“NoneType”对象没有属性“name”您的示例运行良好,即使我把它分开。。。一定是其他问题。我发现了不相关的问题。。。再次感谢。
import click

def importable_command(*args, **kwargs):
    def decorator(f):
        return click.decorators.command(*args, **kwargs)(f)
    return decorator


@importable_command('version')
@click.option('--long')
@click.option('--check')
def version_cmd(long, check):
    click.echo('version long: {}'.format(long))
    click.echo('version check: {}'.format(check))


@click.group()
def cli():
    """An Awesome CLI"""


# Add our version command to this group
cli.add_command(version_cmd)

if __name__ == "__main__":
    commands = (
        'version --long a_long',
        'version --help',
        '--help',
    )

    import sys, time

    time.sleep(1)
    print('Click Version: {}'.format(click.__version__))
    print('Python Version: {}'.format(sys.version))
    for cmd in commands:
        try:
            time.sleep(0.1)
            print('-----------')
            print('> ' + cmd)
            time.sleep(0.1)
            cli(cmd.split())

        except BaseException as exc:
            if str(exc) != '0' and \
                    not isinstance(exc, (click.ClickException, SystemExit)):
                raise
Click Version: 6.7
Python Version: 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)]
-----------
> version --long a_long
version long: a_long
version check: None
-----------
> version --help
Usage: test.py version [OPTIONS]

Options:
  --long TEXT
  --check TEXT
  --help        Show this message and exit.
-----------
> --help
Usage: test.py [OPTIONS] COMMAND [ARGS]...

  An Awesome CLI

Options:
  --help  Show this message and exit.

Commands:
  version