这可以通过构建从派生的自定义类来完成
click.Option,并在该类中使用如下
click.Option.handle_parse_result()方法:
自订类别:
import clickclass NotRequiredIf(click.Option): def __init__(self, *args, **kwargs): self.not_required_if = kwargs.pop('not_required_if') assert self.not_required_if, "'not_required_if' parameter required" kwargs['help'] = (kwargs.get('help', '') + ' NOTE: This argument is mutually exclusive with %s' % self.not_required_if ).strip() super(NotRequiredIf, self).__init__(*args, **kwargs) def handle_parse_result(self, ctx, opts, args): we_are_present = self.name in opts other_present = self.not_required_if in opts if other_present: if we_are_present: raise click.UsageError( "Illegal usage: `%s` is mutually exclusive with `%s`" % ( self.name, self.not_required_if)) else: self.prompt = None return super(NotRequiredIf, self).handle_parse_result( ctx, opts, args)使用自定义类:
要使用自定义类,请将
cls参数传递给
click.optiondecorator,如下所示:
@click.option('--username', prompt=True, cls=NotRequiredIf, not_required_if='authentication_token')这是如何运作的?
之所以可行,是因为click是一个设计良好的OO框架。该
@click.option()装饰通常实例化一个
click.Option对象,但允许与被覆盖这种行为
cls参数。因此,
click.Option在我们自己的类中继承并超越所需的方法是相对容易的事情。
在这种情况下,我们在乘坐
click.Option.handle_parse_result()和禁用需要
user/password,如果
authentication-token令牌存在,并且抱怨,如果两者
user/password都
authentication-token存在。
测试代码:
@click.command()@click.option('--authentication-token')@click.option('--username', prompt=True, cls=NotRequiredIf, not_required_if='authentication_token')@click.option('--password', prompt=True, hide_input=True, cls=NotRequiredIf, not_required_if='authentication_token')def login(authentication_token, username, password): click.echo('t:%s u:%s p:%s' % ( authentication_token, username, password))if __name__ == '__main__': login('--username name --password pword'.split()) login('--help'.split()) login(''.split()) login('--username name'.split()) login('--authentication-token token'.split())结果:
来自
login('--username name --password pword'.split()):t:None u:name p:pword
来自
login('--help'.split()):Usage: test.py [OPTIONS]Options: --authentication-token TEXT --username TEXT NOTE: This argument is mutually exclusive with authentication_token --password TEXT NOTE: This argument is mutually exclusive with authentication_token --help Show this message and exit.



