6

我正在使用Click库在 Python 中创建一个命令行应用程序,该库接受名称作为输入,但如果未输入名称,则返回默认值。

这是我到目前为止的代码。

你好.py

import click

@click.version_option(1.0)

@click.command()
@click.argument('string', default='World')
@click.option('-r', '--repeat', default=1, help='How many times should be greeted.')

def cli(string,repeat):
    '''This string greets you.'''
    for i in xrange(repeat): 
        click.echo('Hello %s!' % string)

if __name__ == '__main__':
    cli()

当我运行它时。

$你好

Hello World!

$你好鲍勃

Hello Bob!

$你好鲍勃-r 3

Hello Bob!
Hello Bob!
Hello Bob!

这正是我想要的。

现在,我希望能够像以下示例一样接受来自标准输入的输入。

$回声约翰| 你好

Hello John!

$回声约翰| 你好-r 3

Hello John!
Hello John!
Hello John!
4

2 回答 2

4

好吧,这是一个很老的问题,但无论如何我都会尝试回答。

我是 Click 的新手,所以我认为,我的解决方案可以得到极大的改进。无论如何,它完全符合您的要求。这里是:

import click


def get_name(ctx, param, value):
    if not value and not click.get_text_stream('stdin').isatty():
        return click.get_text_stream('stdin').read().strip()
    else:
        return value


@click.command()
@click.argument('name', callback=get_name, required=False)
@click.option('--repeat', '-r', default=1)
def say_hello(name, repeat):
    for i in range(repeat):
        click.echo('Hello {}'.format(name or 'World'))



if __name__ == "__main__":
    say_hello()
于 2017-08-23T17:00:41.167 回答
3

问题是管道之前的命令结果将在您的应用程序内部使用,而不是作为它的参数。由于您的应用程序本身不使用任何输入,因此您通过管道传输的所有内容都将被丢弃。

如果您希望您的应用程序是“可管道化的”,只需在其中插入一个raw_input,因为此函数从标准输入读取。

为了让你的程序看起来像 cat 你可以这样做:

@click.command()
@click.argument('string', required=False)
@click.option('-r', '--repeat', default=1, help='How many times should be greeted.')
def cli(string, repeat):
    '''This string greets you.'''
    if not string:
        string = raw_input()
    for i in xrange(repeat):
        click.echo('Hello %s!' % string)

另一种选择是在选项中转换字符串并将提示设置为 True:

@click.command()
@click.option('--string', prompt=True)
@click.option('-r', '--repeat', default=1, help='How many times should be greeted.')
def cli(string, repeat):
    '''This string greets you.'''
    for i in xrange(repeat):
        click.echo('Hello %s!' % string)

这样,如果用户没有提供字符串,他将被提示输入,这也使您的应用程序可管道化。唯一的问题是它会打印到标准输出STRING:,这有时是不可接受的(您可以定义一个空字符串以显示prompt='',但是,因为我知道,没有机会摆脱:)。

顺便说一句,为了达到同样的目的,使用你的代码,你可以这样做:

python hello.py `echo bob`

echo bob将首先评估,其结果将构成 hello.py 的参数

于 2015-10-25T05:02:27.197 回答