Dro*_*ror 7 python command-line-interface python-click
使用时click我知道如何定义多项选择选项。我也知道如何将选项设置为必需选项。但是,我怎么能表明一个选项B,只需要在设置选项的值A是foo?
下面是一个例子:
import click
@click.command()
@click.option('--output',
type=click.Choice(['stdout', 'file']), default='stdout')
@click.option('--filename', type=click.STRING)
def main(output, filename):
print("output: " + output)
if output == 'file':
if filename is None:
print("filename must be provided!")
else:
print("filename: " + str(filename))
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
如果output选项是stdout,则filename不需要。但是,如果用户选择output是file,则filename必须提供另一个选项。单击是否支持此模式?
在函数的开头,我可以添加如下内容:
if output == 'file' and filename is None:
raise ValueError('When output is "file", a filename must be provided')
Run Code Online (Sandbox Code Playgroud)
但我对是否有更好/更清洁的解决方案感兴趣。
在这个例子的特殊情况下,我认为一个更简单的方法是摆脱--output,并简单地假设stdoutif--filename未指定,如果--filename指定,则使用它而不是stdout。
但假设这是一个人为的示例,您可以继承 fromclick.Option以允许挂钩点击处理:
class OptionRequiredIf(click.Option):
def full_process_value(self, ctx, value):
value = super(OptionRequiredIf, self).full_process_value(ctx, value)
if value is None and ctx.params['output'] == 'file':
msg = 'Required if --output=file'
raise click.MissingParameter(ctx=ctx, param=self, message=msg)
return value
Run Code Online (Sandbox Code Playgroud)
要使用自定义类,请将其作为 cls 参数传递给选项装饰器,例如:
@click.option('--filename', type=click.STRING, cls=OptionRequiredIf)
Run Code Online (Sandbox Code Playgroud)
import click
@click.command()
@click.option('--output',
type=click.Choice(['stdout', 'file']), default='stdout')
@click.option('--filename', type=click.STRING, cls=OptionRequiredIf)
def main(output, filename):
print("output: " + output)
if output == 'file':
if filename is None:
print("filename must be provided!")
else:
print("filename: " + str(filename))
main('--output=file'.split())
Run Code Online (Sandbox Code Playgroud)
Usage: test.py [OPTIONS]
Error: Missing option "--filename". Required if --output=file
Run Code Online (Sandbox Code Playgroud)