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:元组索引超出范围
要默认为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=-1和type=click.File('r')参数。