Python 3 + Click:当从一个命令调用另一个命令时,CLI 参数会被破坏
Python 3 + Click: CLI arguments get butchered when calling one command from another
我正在使用 Python 3.9 和 Click to build a small command line interface utility,但我遇到了奇怪的错误,特别是当我试图从另一个函数调用装饰为 @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()
这是我 运行 我的脚本同时使用 inner
和 outer
命令时的 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'>
%
显然,装饰器以某种方式混淆了参数。任何人都可以解释 为什么 这是,并且 如何 我可以实现传递参数不变的预期行为?也许我遗漏了一些非常明显的东西?
提前致谢!
使用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()
我正在使用 Python 3.9 和 Click to build a small command line interface utility,但我遇到了奇怪的错误,特别是当我试图从另一个函数调用装饰为 @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()
这是我 运行 我的脚本同时使用 inner
和 outer
命令时的 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'>
%
显然,装饰器以某种方式混淆了参数。任何人都可以解释 为什么 这是,并且 如何 我可以实现传递参数不变的预期行为?也许我遗漏了一些非常明显的东西?
提前致谢!
使用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()