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')
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]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.