【问题标题】:Python 3 + Click: CLI arguments get butchered when calling one command from anotherPython 3 + Click:当从另一个命令调用一个命令时,CLI 参数会被破坏
【发布时间】:2021-09-10 15:54:08
【问题描述】:

我正在使用 Python 3.9 并单击以构建一个小型命令行界面实用程序,但我遇到了奇怪的错误,特别是当我尝试从另一个同样装饰的函数调用一个装饰为 @click.command() 的函数时.

我已将我的程序精简到最低限度来解释我的意思。

这是我的程序

import click

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

@click.command()
@click.argument('id')
def outer(id):
    print('outer id',id,type(id))
    inner(id)  # run inner() from within outer(), pass argument unchanged

@click.command()       # *
@click.argument('id')  # *
def inner(id):
    print('inner id',id,type(id))

cli.add_command(outer)
cli.add_command(inner)  # *

if __name__ == '__main__':
    cli()

这是我同时使用 innerouter 命令运行脚本时的 CLI 结果:

% python3 test.py inner 123
inner id 123 <class 'str'>
% python3 test.py outer 123
outer id 123 <class 'str'>
Usage: test.py [OPTIONS] ID
Try 'test.py --help' for help.

Error: Got unexpected extra arguments (2 3)
%

有趣的是,当我使用单个字符参数时它可以工作:

% python3 test.py outer 1
outer id 1 <class 'str'>
inner id 1 <class 'str'>
%

如果我注释掉标有# * 的三行,则运行outer 命令的行为与预期一样,将id 参数传递给inner() 而不会发生任何变化或问题,无论参数的长度如何:

% python3 test.py outer 123
outer id 123 <class 'str'>
inner id 123 <class 'str'>
%

显然,装饰器在某种程度上弄乱了参数。任何人都可以解释为什么这是,以及如何我可以实现传递参数不变的期望行为?也许我错过了一些非常明显的东西?

提前致谢!

【问题讨论】:

    标签: python command-line-interface python-click


    【解决方案1】:

    使用context operations 调用其他命令

    import click
    
    @click.group()
    def cli():
        pass
    
    @click.command()
    @click.argument('id')
    @click.pass_context
    def outer(ctx, id):
        print('outer id',id,type(id))
        ctx.forward(inner)  # run inner(), pass argument unchanged
        ctx.invoke(inner, id=id+1) # run inner(), pass modified argument
    
    @click.command()       # *
    @click.argument('id')  # *
    def inner(id):
        print('inner id',id,type(id))
    
    cli.add_command(outer)
    cli.add_command(inner)  # *
    
    if __name__ == '__main__':
        cli()
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多