从单击命令中调用另一个单击命令

从单击命令中调用另一个单击命令

问题描述:

我想使用一些有用的功能作为命令.为此,我正在测试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_nameadd_surnameadd_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_nameadd_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:

  1. Context.invoke()-使用您提供的参数调用另一个命令
  2. 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

参考: http://click.pocoo.org/6/advanced/#invoking-other -命令