ArgumentParser:具有可选值的可选参数

ArgumentParser: Optional argument with optional value

如果我有一个带有可选参数值的可选参数,有没有办法在未给出值时验证是否设置了参数?

例如:

parser = argparse.ArgumentParser()
parser.add_argument('--abc', nargs='?')
args = parser.parse_args()

会正确地给我:

optional arguments:
    --abc [ABC]

如何区分下面的1和2?

  1. '' => args.abc 是 None
  2. '--abc' => args.abc 仍然是 None
  3. '--abc something' => args.abc 是 something

...

更新:

找到解决这个问题的技巧:可以使用"nargs='*'"代替"nargs='?'"。这样#1 将 return None,#2 将 return 一个空列表。缺点是这将允许参数的多个值也被接受;所以你需要在适当的时候为它添加一个检查。

或者你也可以为参数设置一个默认值;请参阅 chepner 和 Anand S Kumar 的回答。

为该选项使用不同的默认值。比较

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--abc', nargs='?', default="default")
>>> parser.parse_args()
Namespace(abc='default')
>>> parser.parse_args(['--abc'])
Namespace(abc=None)
>>> parser.parse_args(['--abc', 'value'])
Namespace(abc='value')

我不确定在没有参数的情况下使用 --abc 时如何提供不同的值,而不是使用自定义操作而不是 nargs 参数。

不确定这是否是标准方式,但您可以将 default 参数设置为某物,然后在 --abc 不在参数列表中的情况下使用该值。

示例代码-

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--abc', nargs='?', default="-1")
args = parser.parse_args()
print(args)

结果-

>python a.py
Namespace(abc='-1')

>python a.py --abc
Namespace(abc=None)

>python a.py --abc something
Namespace(abc='something')

使用 nargs='?',您可以同时提供 defaultconst

In [791]: parser=argparse.ArgumentParser()    
In [792]: parser.add_argument('--abc', nargs='?', default='default', const='const')

如果未给出参数,则使用默认值:

In [793]: parser.parse_args([])
Out[793]: Namespace(abc='default')

如果给定,但没有参数字符串,它使用常量:

In [794]: parser.parse_args(['--abc'])
Out[794]: Namespace(abc='const')

否则它使用参数字符串:

In [795]: parser.parse_args(['--abc','test'])
Out[795]: Namespace(abc='test')

In [796]: parser.print_help()
usage: ipython3 [-h] [--abc [ABC]]

optional arguments:
  -h, --help   show this help message and exit
  --abc [ABC]

我正在使用它来获得一个用于多处理的 command-line arg。指定 --multi 使用所有内核并给定一个 arg 指定多个内核,例如,--multi 4 表示四个内核。

parser.add_argument("-mp", "--multi", type=int, nargs="*", help=multi_text)

解析逻辑为:

    if (args.multi == None):
        num_cores = 1
    elif (args.multi == []):
        num_cores = multiprocessing.cpu_count()
    elif (len(args.multi) == 1):
        num_cores = args.multi[0]
    else:
        print("Invalid specification of core usage.")
        sys.exit(1)