I know that does not make sense multiple positional arguments into a mutually exclusive group because you can't say who is who. But I need to include ONE positional argument into that.
What I need:
$ myprogram -h
usage: myprogram [-h] [--delete value | --update value | value]
Where positional value
is the default action (kind of "--include"). (myprogram
without arguments must be valid too).
My first attempt (this doesn't works):
parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('--delete', metavar='value')
group.add_argument('--update', metavar='value')
group.add_argument('value')
Is that possible?
Second attempt:
parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('--delete', action='store_true')
group.add_argument('--update', action='store_true')
group.add_argument('--insert', action='store_true', default=True)
group.add_argument('value')
After importing the library, argparse. ArgumentParser() initializes the parser so that you can start to add custom arguments. To add your arguments, use parser. add_argument() .
In logic, two mutually exclusive propositions are propositions that logically cannot be true in the same sense at the same time. To say that more than two propositions are mutually exclusive, depending on the context, means that one cannot be true if the other one is true, or at least one of them cannot be true.
Number of Arguments If you want your parameters to accept a list of items you can specify nargs=n for how many arguments to accept. Note, if you set nargs=1 , it will return as a list not a single value.
I'd do this a little bit differently:
parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.set_defaults(mode='insert')
group.add_argument('--delete', action='store_const', dest='mode', const='delete')
group.add_argument('--update', action='store_const', dest='mode', const='update')
group.add_argument('--insert', action='store_const', dest='mode', const='insert')
parser.add_argument('value', nargs='?')
args = parser.parse_args()
If you additionally want to make program --delete
(with no value
option) fail, add
if args.mode != 'insert' and args.value:
parser.error("can't {} without a value argument".format(args.mode))
Note that this will mean that program --insert
(with no value
) still works. You could avoid this with a little more effort by having the default mode
be None
, doing the check above with args.mode is not None
, and then doing if args.mode is None: args.mode = 'insert'
or similar.
Your syntax is more clearly described as:
myprogram {--insert|--update|--delete} value
where --insert
defaults to True and value is required.
argparse
can make you feel like your desired syntax must fit its model when something like
if args.insert and (args.update or args.delete):
parser.print_help()
is much more obvious.
Added in response to comment:
Here is pseudo-code (meaning I didn't test it) which shows how I would implement this:
parser.add_argument('--insert', action='store_true')
parser.add_argument('--update', action='store_true')
parser.add_argument('--delete', action='store_true')
parser.add_argument('value')
args = parser.parse_args(sys.argv)
if ((args.insert and args.delete) or
(args.insert and args.update) or
(args.update and args.delete)):
# can't pick more than one, complain and quit
elif not (args.update or args.delete):
# they specified no action so assume insert
args.insert = True
# now one and only one of insert/update/delete is
# True and args.value contains the argument
I hope that makes things more clear.
Make the positional argument optional (with '?')
parser = ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('--delete', metavar='value')
group.add_argument('--update', metavar='value')
group.add_argument('value', nargs='?')
usage is then:
usage: ipython [-h] [--delete value | --update value | value]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With