import click
def std_cb(ctx, param, standardize):
if standardize:
opt = click.Option(param_decls=['-a'],
help='this option only exists when -S is set')
else:
opt = click.Option(param_decls=['-b'],
help='this option only exists when -S is not set')
ctx.command.params.append(opt)
return standardize
@click.command()
@click.option('-S', '--standardize/--no-standardize', is_eager=True,
is_flag=True, default=False, callback=std_cb)
def get_options(standardize, **extra_opts):
print(locals())
if __name__ == '__main__':
uis = get_options.main(standalone_mode=False)
我要实现的目标是能够使用单击库为给定命令动态创建不同选项,具体取决于对同一命令的渴望标志选项的值。
当我在CLI上以$ python cli_test.py
的身份执行上述命令时,将按预期打印到标准输出{'standardize': False, 'extra_opts': {}}
。同样,$ python cli_test.py -S
打印{'standardize': True, 'extra_opts': {}}
,也可以预期。
并且当我用--help
调用内置的$ python cli_test.py --help
选项时,我得到:
Usage: cli_test.py [OPTIONS]
Options:
-S, --standardize / --no-standardize
-b TEXT this option only exists when -S is not set
--help Show this message and exit.
[这似乎暗示通过--no-standardize
标志通过std_cb
回调附加-S
特定选项的工作也正常。
类似地,$ python cli_test.py --help -S
产生:
Usage: cli_test.py [OPTIONS]
Options:
-S, --standardize / --no-standardize
-a TEXT this option only exists when -S is set
--help Show this message and exit.
由于-a
标志的出现,现在出现-S
选项。
但是,如果我尝试执行$ python cli_test.py -b hello
,则会收到错误:click.exceptions.NoSuchOption: no such option: -b
。
[类似地,尽管$ python cli_test.py -S -a world
会在其适用的click.exceptions.NoSuchOption: no such option: -a
标志值下显示在帮助页面中,但它们仍会产生-S
。>>
我期望从给定的代码示例中看到的当然是$ python cli_test.py -b hello
打印{'standardize': True, 'extra_opts': {'b': 'hello'}}
。
和$ python cli_test.py -S -a world
打印{'standardize': True, 'extra_opts': {'a': 'world'}}
。
[在Click docs中,作者确实声明使用@click.option
等同于手动创建Option实例并将其附加到Command.params
列表。”,所以我不确定我在做什么。错误。
我的代码示例:导入click def std_cb(ctx,param,standardize):如果标准化:opt = click.Option(param_decls = ['-a'],help ='此选项仅在-S ...时存在) >
import click
def require_standardize_set(ctx, param, value):
if value and not ctx.params['standardize']:
raise click.UsageError('-{} requires that -S is set'.format(param.name))
return value
def require_standardize_not_set(ctx, param, value):
if value and ctx.params['standardize']:
raise click.UsageError('-{} requires that -S is not set'.format(param.name))
return value
@click.command()
@click.option('-S', '--standardize/--no-standardize',
is_flag=True, default=False, is_eager=True)
@click.option('-a', help='this option requires that -S is set',
callback=require_standardize_set)
@click.option('-b', help='this option requires that -S is not set',
callback=require_standardize_not_set)
def get_options(standardize, **extra_opts):
print(locals())
if __name__ == '__main__':
uis = get_options.main(standalone_mode=False)
在我看来这将产生相同的结果(除了extra_opts
始终同时包含a
和b
,但如果未设置,则具有None
的值)。从我的角度来看,这样做的好处是文档总是记录a
和b
。作为用户,我想我会想要的。