Is there a way to create argument in python's argparse that returns true in case no values given

六月ゝ 毕业季﹏ 提交于 2019-12-01 21:51:20

问题


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:

  1. python ./my_script.py --resize # Will contain True that means, resize all the objects
  2. python ./my_script.py --resize <index> # Will contain index, that means resize only specific object

回答1:


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:

  1. Not specified: The argument will get its default value (None by default):

    >>> parser.parse_args(''.split())
    Namespace(resize=None)
    
  2. Specified without a value: The argument will get its const value:

    >>> parser.parse_args('--resize'.split())
    Namespace(resize=True)
    
  3. 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()



回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/34651824/is-there-a-way-to-create-argument-in-pythons-argparse-that-returns-true-in-case

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!