问题
How can I create a mutually exclusive option group in Click? I want to either accept the flag "--all" or take an option with a parameter like "--color red".
回答1:
I ran into this same use case recently; this is what I came up with. For each option, you can give a list of conflicting options.
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
)
Then use the regular option
decorator but pass the cls
argument:
@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 that includes the code above and shows the output from running it.
If that won't work for you, there's also a few (closed) issues mentioning this on the click github page with a couple of ideas that you may be able to use.
- https://github.com/pallets/click/issues/257
- https://github.com/pallets/click/issues/509
回答2:
You could use the following package: 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 help:
$ app.py --help
Usage: app.py [OPTIONS]
Options:
Grouped options: [mutually_exclusive, required]
Group description
--all
--color TEXT
--help Show this message and exit.
来源:https://stackoverflow.com/questions/37310718/mutually-exclusive-option-groups-in-python-click