python 中的互斥选项组 单击
Mutually exclusive option groups in python Click
如何在Click中创建互斥的选项组?我想要么接受标志“--all”,要么选择带有“--color red”之类的参数的选项。
我最近 运行 进入了这个相同的用例;这就是我想出的。对于每个选项,您可以给出一个冲突选项列表。
from click import command, option, Option, UsageError
class MutuallyExclusiveOption(Option):
def __init__(self, *args, **kwargs):
self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
help = kwargs.get('help', '')
if self.mutually_exclusive:
ex_str = ', '.join(self.mutually_exclusive)
kwargs['help'] = help + (
' NOTE: This argument is mutually exclusive with '
' arguments: [' + ex_str + '].'
)
super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
def handle_parse_result(self, ctx, opts, args):
if self.mutually_exclusive.intersection(opts) and self.name in opts:
raise UsageError(
"Illegal usage: `{}` is mutually exclusive with "
"arguments `{}`.".format(
self.name,
', '.join(self.mutually_exclusive)
)
)
return super(MutuallyExclusiveOption, self).handle_parse_result(
ctx,
opts,
args
)
然后使用常规 option
装饰器但传递 cls
参数:
@command(help="Run the command.")
@option('--jar-file', cls=MutuallyExclusiveOption,
help="The jar file the topology lives in.",
mutually_exclusive=["other_arg"])
@option('--other-arg',
cls=MutuallyExclusiveOption,
help="The jar file the topology lives in.",
mutually_exclusive=["jar_file"])
def cli(jar_file, other_arg):
print "Running cli."
print "jar-file: {}".format(jar_file)
print "other-arg: {}".format(other_arg)
if __name__ == '__main__':
cli()
Here's a gist
包含上面的代码并显示 运行 它的输出。
如果这对您不起作用,还有一些(已解决的)问题在点击 github 页面上提到了这一点,其中包含一些您可能可以使用的想法。
您可以使用以下包:
https://github.com/espdev/click-option-group
import click
from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup
@click.command()
@optgroup.group('Grouped options', cls=RequiredMutuallyExclusiveOptionGroup,
help='Group description')
@optgroup.option('--all', 'all_', is_flag=True, default=False)
@optgroup.option('--color')
def cli(all_, color):
print(all_, color)
if __name__ == '__main__':
cli()
应用帮助:
$ app.py --help
Usage: app.py [OPTIONS]
Options:
Grouped options: [mutually_exclusive, required]
Group description
--all
--color TEXT
--help Show this message and exit.
您可以使用 Cloup,这是一个向 Click 添加选项组和约束的包。在 Cloup 中你有两种选择来解决这个问题。
免责声明:我是包的作者。
选项 1:@option_group
当您使用 @option_group
定义选项组时,每个组中的选项显示在单独的帮助部分(如在 argparse 中)。您可以将约束(如 mutually_exclusive
)应用到选项组,如下所示:
from cloup import command, option, option_group
from cloup.constraints import mutually_exclusive
@command()
@option_group(
'Color options',
option('--all', 'all_colors', is_flag=True),
option('--color'),
constraint=mutually_exclusive
)
def cmd(**kwargs):
print(kwargs)
帮助将是:
Usage: cmd [OPTIONS]
Color options [mutually exclusive]:
--all
--color TEXT
Other options:
--help Show this message and exit.
选项 2:应用约束而不定义选项组
如果您不希望选项组出现在命令帮助中,您可以使用 @constraint
并通过它们的(目标)名称指定约束选项:
from cloup import command, option
from cloup.constraints import constraint, mutually_exclusive
@command()
@option('--all', 'all_colors', is_flag=True)
@option('--color')
@constraint(mutually_exclusive, ['all_colors', 'color'])
def cmd(**kwargs):
print(kwargs)
可以在命令帮助中记录以这种方式定义的约束!默认情况下禁用此功能,但可以通过 show_constraints=True
到 @command
轻松启用。结果:
Usage: cmd [OPTIONS]
Options:
--all
--color TEXT
--help Show this message and exit.
Constraints:
{--all, --color} mutually exclusive
更新: 现在可以使用约束作为装饰器,而不是使用 @contraint
:
@command()
@mutually_exclusive(
option('--all', 'all_colors', is_flag=True),
option('--color'),
)
def cmd(**kwargs):
print(kwargs)
错误信息
在这两种情况下,如果您 运行 cmd --all --color red
,您将得到:
Usage: cmd [OPTIONS]
Try 'cmd --help' for help.
Error: the following parameters are mutually exclusive:
--all
--color
其他约束条件
Cloup 定义了应满足您 99.9% 需求的约束。它甚至支持条件约束!
例如,如果用户必须提供您的互斥选项之一,请将上例中的 mutually_exclusive
替换为 RequireExactly(1)
。
您可以找到所有可用的约束条件 here。
如何在Click中创建互斥的选项组?我想要么接受标志“--all”,要么选择带有“--color red”之类的参数的选项。
我最近 运行 进入了这个相同的用例;这就是我想出的。对于每个选项,您可以给出一个冲突选项列表。
from click import command, option, Option, UsageError
class MutuallyExclusiveOption(Option):
def __init__(self, *args, **kwargs):
self.mutually_exclusive = set(kwargs.pop('mutually_exclusive', []))
help = kwargs.get('help', '')
if self.mutually_exclusive:
ex_str = ', '.join(self.mutually_exclusive)
kwargs['help'] = help + (
' NOTE: This argument is mutually exclusive with '
' arguments: [' + ex_str + '].'
)
super(MutuallyExclusiveOption, self).__init__(*args, **kwargs)
def handle_parse_result(self, ctx, opts, args):
if self.mutually_exclusive.intersection(opts) and self.name in opts:
raise UsageError(
"Illegal usage: `{}` is mutually exclusive with "
"arguments `{}`.".format(
self.name,
', '.join(self.mutually_exclusive)
)
)
return super(MutuallyExclusiveOption, self).handle_parse_result(
ctx,
opts,
args
)
然后使用常规 option
装饰器但传递 cls
参数:
@command(help="Run the command.")
@option('--jar-file', cls=MutuallyExclusiveOption,
help="The jar file the topology lives in.",
mutually_exclusive=["other_arg"])
@option('--other-arg',
cls=MutuallyExclusiveOption,
help="The jar file the topology lives in.",
mutually_exclusive=["jar_file"])
def cli(jar_file, other_arg):
print "Running cli."
print "jar-file: {}".format(jar_file)
print "other-arg: {}".format(other_arg)
if __name__ == '__main__':
cli()
Here's a gist 包含上面的代码并显示 运行 它的输出。
如果这对您不起作用,还有一些(已解决的)问题在点击 github 页面上提到了这一点,其中包含一些您可能可以使用的想法。
您可以使用以下包: https://github.com/espdev/click-option-group
import click
from click_option_group import optgroup, RequiredMutuallyExclusiveOptionGroup
@click.command()
@optgroup.group('Grouped options', cls=RequiredMutuallyExclusiveOptionGroup,
help='Group description')
@optgroup.option('--all', 'all_', is_flag=True, default=False)
@optgroup.option('--color')
def cli(all_, color):
print(all_, color)
if __name__ == '__main__':
cli()
应用帮助:
$ app.py --help
Usage: app.py [OPTIONS]
Options:
Grouped options: [mutually_exclusive, required]
Group description
--all
--color TEXT
--help Show this message and exit.
您可以使用 Cloup,这是一个向 Click 添加选项组和约束的包。在 Cloup 中你有两种选择来解决这个问题。
免责声明:我是包的作者。
选项 1:@option_group
当您使用 @option_group
定义选项组时,每个组中的选项显示在单独的帮助部分(如在 argparse 中)。您可以将约束(如 mutually_exclusive
)应用到选项组,如下所示:
from cloup import command, option, option_group
from cloup.constraints import mutually_exclusive
@command()
@option_group(
'Color options',
option('--all', 'all_colors', is_flag=True),
option('--color'),
constraint=mutually_exclusive
)
def cmd(**kwargs):
print(kwargs)
帮助将是:
Usage: cmd [OPTIONS]
Color options [mutually exclusive]:
--all
--color TEXT
Other options:
--help Show this message and exit.
选项 2:应用约束而不定义选项组
如果您不希望选项组出现在命令帮助中,您可以使用 @constraint
并通过它们的(目标)名称指定约束选项:
from cloup import command, option
from cloup.constraints import constraint, mutually_exclusive
@command()
@option('--all', 'all_colors', is_flag=True)
@option('--color')
@constraint(mutually_exclusive, ['all_colors', 'color'])
def cmd(**kwargs):
print(kwargs)
可以在命令帮助中记录以这种方式定义的约束!默认情况下禁用此功能,但可以通过 show_constraints=True
到 @command
轻松启用。结果:
Usage: cmd [OPTIONS]
Options:
--all
--color TEXT
--help Show this message and exit.
Constraints:
{--all, --color} mutually exclusive
更新: 现在可以使用约束作为装饰器,而不是使用 @contraint
:
@command()
@mutually_exclusive(
option('--all', 'all_colors', is_flag=True),
option('--color'),
)
def cmd(**kwargs):
print(kwargs)
错误信息
在这两种情况下,如果您 运行 cmd --all --color red
,您将得到:
Usage: cmd [OPTIONS]
Try 'cmd --help' for help.
Error: the following parameters are mutually exclusive:
--all
--color
其他约束条件
Cloup 定义了应满足您 99.9% 需求的约束。它甚至支持条件约束!
例如,如果用户必须提供您的互斥选项之一,请将上例中的 mutually_exclusive
替换为 RequireExactly(1)
。
您可以找到所有可用的约束条件 here。