从单击命令中调用另一个单击命令
我想使用一些有用的功能作为命令.为此,我正在测试click
库.我定义了三个原始函数,然后将其装饰为click.command
:
I want to use some useful functions as commands. For that I am testing the click
library. I defined my three original functions then decorated as click.command
:
import click
import os, sys
@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=True)
def add_name(content, to_stdout=False):
if not content:
content = ''.join(sys.stdin.readlines())
result = content + "\n\tadded name"
if to_stdout is True:
sys.stdout.writelines(result)
return result
@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=True)
def add_surname(content, to_stdout=False):
if not content:
content = ''.join(sys.stdin.readlines())
result = content + "\n\tadded surname"
if to_stdout is True:
sys.stdout.writelines(result)
return result
@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=False)
def add_name_and_surname(content, to_stdout=False):
result = add_surname(add_name(content))
if to_stdout is True:
sys.stdout.writelines(result)
return result
这样,我可以使用setup.py
文件和pip install --editable .
生成三个命令add_name
,add_surname
和add_name_and_surname
,然后可以通过管道进行操作:
This way I am able to generate the three commands add_name
, add_surname
and add_name_and_surname
using a setup.py
file and pip install --editable .
Then I am able to pipe:
$ echo "original content" | add_name | add_surname
original content
added name
added surname
但是,使用不同的单击命令作为函数时,我需要解决一个小问题:
However there is one slight problem I need to solve, when composing with different click commands as functions:
$echo "original content" | add_name_and_surname
Usage: add_name_and_surname [OPTIONS] [CONTENT]
Error: Got unexpected extra arguments (r i g i n a l c o n t e n t
)
我不知道为什么它不起作用,我需要这个add_name_and_surname
命令来调用add_name
和add_surname
而不是作为命令而是作为函数来调用,否则它违背了我将函数既用作库函数又用作库的目的.命令.
I have no clue why it does not work, I need this add_name_and_surname
command to call add_name
and add_surname
not as command but as functions, else it defeats my original purpose of using functions as both library functions and commands.
由于单击修饰符,不能仅通过指定参数来调用函数. Context 类在这里是您的朋友,
Due to the click decorators the functions can no longer be called just by specifying the arguments. The Context class is your friend here, specifically:
- Context.invoke()-使用您提供的参数调用另一个命令
- Context.forward()-填写当前命令中的参数
因此您的add_name_and_surname代码应如下所示:
So your code for add_name_and_surname should look like:
@click.command()
@click.argument('content', required=False)
@click.option('--to_stdout', default=False)
@click.pass_context
def add_name_and_surname(ctx, content, to_stdout=False):
result = ctx.invoke(add_surname, content=ctx.forward(add_name))
if to_stdout is True:
sys.stdout.writelines(result)
return result