如何为单击处理的参数列表指定默认值?

cod*_*ter 2 python command-line-interface command-line-arguments python-click

我有这行代码,预计会获取传递给我的 Python 脚本的所有文件名:

@click.argument("logs", nargs=-1, type=click.File('r'), required=1)
Run Code Online (Sandbox Code Playgroud)

当没有传递文件名时,我想默认为-,即标准输入。所以,如果我尝试:

@click.argument("logs", nargs=-1, type=click.File('r'), required=1, default="-")
Run Code Online (Sandbox Code Playgroud)

单击变得不高兴并抛出此错误:

TypeError: 不支持 nargs=-1 与默认值的组合。

有解决方法吗?我尝试设置nargs=0但引发了不同的错误:

IndexError:元组索引超出范围

Ste*_*uch 5

要默认为stdin可能为空的文件列表,您可以定义一个自定义参数类,例如:

定制类:

class FilesDefaultToStdin(click.Argument):
    def __init__(self, *args, **kwargs):
        kwargs['nargs'] = -1
        kwargs['type'] = click.File('r')
        super().__init__(*args, **kwargs)

    def full_process_value(self, ctx, value):
        return super().process_value(ctx, value or ('-', ))
Run Code Online (Sandbox Code Playgroud)

将此行为定义为类可以方便地重用。

要使用自定义类:

@click.command()
@click.argument("logs", cls=FilesDefaultToStdin)
def main(logs):
    ...
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

这是可行的,因为 click 是一个设计良好的 OO 框架。装饰@click.argument()器通常会实例化一个click.Argument对象,但允许使用参数覆盖此行为cls。因此,在我们自己的类中继承click.Argument并覆盖所需的方法是一件相对容易的事情。

在这种情况下,我们覆盖click.Argument.full_process_value(). 在我们的代码中full_process_value(),我们查找一个空的参数列表,如果为空,我们将-(stdin) 参数添加到列表中。

此外,我们自动分配nargs=-1type=click.File('r')参数。