Argparse互斥组不适用于位置和可选参数对

时间:2018-09-11 18:44:49

标签: python-3.x command-line-arguments argparse

我写了一个代码,在其中我希望输入文件作为命令行参数。我希望用户以两种方式提供该信息:

  1. 使用标志--input,例如:

    python3 prog.py --input A.cpp

  2. 完全没有任何标志

    python3 prog.py A.cpp

两者都应相同。

我用argparse为其编写了一个程序。

#!/usr/bin/env python3
import argparse
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    input_file = parser.add_mutually_exclusive_group()
    input_file.add_argument('inp',nargs='?',help='file name')
    input_file.add_argument('--input',dest='inp',help='file name')
    args = parser.parse_args()
    print(args)

它适用于:

$ python3 prog.py A.cpp
Namespace(inp='A.cpp')

而不是:

$ python3 prog.py --input A.cpp
Namespace(inp=None)

我希望两种方式都可以互斥,也要它们的价值去保存目的地(就像我在这里inp所做的那样)。一个人可能会跳过两者。表示不需要。

我如何实现?

1 个答案:

答案 0 :(得分:0)

问题出在常见的dest上。位置的默认值是覆盖可选值。

In [13]: p = argparse.ArgumentParser()
In [14]: a1 = p.add_argument('--foo')
In [15]: a2 = p.add_argument('bar', nargs='?', default='default')

In [16]: p.parse_args('xxx'.split())
Out[16]: Namespace(bar='xxx', foo=None)

In [17]: p.parse_args('--foo 1'.split())
Out[17]: Namespace(bar='default', foo='1')

进行更改,以便他们共享dest

In [18]: a1.dest = 'bar'

先解析可选内容,然后解析位置。由于它是'?',因此默认值位于名称空间中,覆盖了先前的值

In [19]: p.parse_args('--foo 1'.split())
Out[19]: Namespace(bar='default')

在这里,可选值覆盖了位置值:

In [20]: p.parse_args('xxx --foo 1'.split())
Out[20]: Namespace(bar='1')

此处的显式位置值覆盖了可选内容:

In [21]: p.parse_args('--foo 1 xxx'.split())
Out[21]: Namespace(bar='xxx')

我意识到差异很微妙。它与如何解析位置和可选内容有关,也与如何处理nargs='?'位置有关。