argparse: let the same required argument be positional OR optional

不想你离开。 提交于 2020-01-05 06:44:26

问题


I would like to have a required command line argument passed as a positional argument or an optional argument. For example, I would like the same action be performed from any of the following invocations:

prog 10
prog -10
prog -n 10
prog --num 10

Is this possible with argparse?


回答1:


With a mutually exclusive group I can create a reasonable approximation:

In an interactive session:

In [10]: parser=argparse.ArgumentParser()
In [11]: grp=parser.add_mutually_exclusive_group(required=True)
In [12]: a=grp.add_argument('pos',nargs='?',type=int,default=0)
In [13]: b=grp.add_argument('-n','--num')

grp can contain any number of optionals, and one optional positional. I chose a different type for the positional just a highlight the difference.

Just the positional value:

In [14]: parser.parse_args(['10'])
Out[14]: Namespace(num=None, pos=10)

Various forms of the optional:

In [16]: parser.parse_args(['-n10'])
Out[16]: Namespace(num='10', pos=0)
In [17]: parser.parse_args(['--num=10'])
Out[17]: Namespace(num='10', pos=0)
In [18]: parser.parse_args(['--num','10'])
Out[18]: Namespace(num='10', pos=0)

test the group exclusivity

In [25]: parser.parse_args(['--num=20','10'])
usage: ipython3 [-h] [-n NUM] [pos]
ipython3: error: argument pos: not allowed with argument -n/--num

and group required:

In [26]: parser.parse_args([])
usage: ipython3 [-h] [-n NUM] [pos]
ipython3: error: one of the arguments pos -n/--num is required

I experimented with giving the positional the same dest as the optional - so both would write to num. But this results in the positional over writing the dest with its default (I can add details if needed)

In [19]: a.dest
Out[19]: 'pos'
In [20]: a.dest='num'
In [21]: parser.parse_args(['--num','10'])
Out[21]: Namespace(num=0)

Post parsing code will have to handle the args.pos and args.num values in what ever way makes sense.

The '-10' input is impossible to handle. Well, I could define:

parser.add_argument('-1')

but the result is probably not what you want:

In [31]: parser.parse_args(['--num=20','-12'])
Out[31]: Namespace(1='2', num='20', pos=0)

Overall this requirement makes things unnecessarily difficult for you the programmer.



来源:https://stackoverflow.com/questions/39974093/argparse-let-the-same-required-argument-be-positional-or-optional

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