Reputation: 3801
Currently --resize
flag that I created is boolean, and means that all my objects will be resized:
parser.add_argument("--resize", action="store_true", help="Do dictionary resize")
# ...
# if resize flag is true I'm re-sizing all objects
if args.resize:
for object in my_obects:
object.do_resize()
Is there a way implement argparse argument that if passed as boolean flag (--resize
) will return true, but if passed with value (--resize 10
), will contain value.
Example:
python ./my_script.py --resize # Will contain True that means, resize all the objects
python ./my_script.py --resize <index> # Will contain index, that means resize only specific object
Upvotes: 3
Views: 1420
Reputation: 387745
In order to optionally accept a value, you need to set nargs
to '?'
. This will make the argument consume one value if it is specified. If the argument is specified but without value, then the argument will be assigned the argument’s const
value, so that’s what you need to specify too:
parser = argparse.ArgumentParser()
parser.add_argument('--resize', nargs='?', const=True)
There are now three cases for this argument:
Not specified: The argument will get its default value (None
by default):
>>> parser.parse_args(''.split())
Namespace(resize=None)
Specified without a value: The argument will get its const value:
>>> parser.parse_args('--resize'.split())
Namespace(resize=True)
Specified with a value: The argument will get the specified value:
>>> parser.parse_args('--resize 123'.split())
Namespace(resize='123')
Since you are looking for an index, you can also specify type=int
so that the argument value will be automatically parsed as an integer. This will not affect the default or const case, so you still get None
or True
in those cases:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--resize', nargs='?', type=int, const=True)
>>> parser.parse_args('--resize 123'.split())
Namespace(resize=123)
Your usage would then look something like this:
if args.resize is True:
for object in my_objects:
object.do_resize()
elif args.resize:
my_objects[args.resize].do_resize()
Upvotes: 8
Reputation: 69
Use nargs
to accept different number of command-line arguments
Use default
and const
to set the default value of resize
see here for details: https://docs.python.org/3/library/argparse.html#nargs
parser.add_argument('-resize', dest='resize', type=int, nargs='?', default=False, const=True)
>>tmp.py -resize 1
args.resize: 1
>>tmp.py -resize
args.resize: True
>>tmp.py
args.resize: False
Upvotes: 2
Reputation: 321
You can add default=False
, const=True
and nargs='?'
to the argument definition and remove action
. This way if you don't pass --resize
it will store False, if you pass --resize
with no argument will store True
and otherwise the passed argument. Still you will have to refactor the code a bit to know if you have index to delete or delete all objects.
Upvotes: 2