【问题标题】:ArgumentParser: Optional argument with optional valueArgumentParser:具有可选值的可选参数
【发布时间】:2015-10-27 05:37:54
【问题描述】:

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

例如:

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

会正确地给我:

optional arguments:
    --abc [ABC]

如何区分下面的1和2?

  1. '' => args.abc 为无
  2. '--abc' => args.abc 仍然是 None
  3. '--abc something' => args.abc 是什么东西

...

更新:

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

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

【问题讨论】:

  • 请注意,您可以使用 vars(args) 将 Namespace 转换为 dict 并在脚本中检查以确定 args 的设置方式。

标签: python argparse


【解决方案1】:

使用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')

如果给出,但没有参数字符串,它使用 const:

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]

【讨论】:

  • 此外,您可以提供choices 参数来限制参数的值。使用'foo', choices=[False], const=True, default='default,' nargs='?'foo 在不带参数的情况下为TrueFalse 如果显式设置为False,并且易于过滤,因此可选。
【解决方案2】:

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

>>> 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 参数。

【讨论】:

  • 感谢您的快速回答。设置默认值应该可以。我刚刚找到了另一种使用 nargs='*' 而不是 nargs='?' 的方法。将在几秒钟内更新我的问题。
  • nargs='*' 做了一些不同的事情;因为它允许任意数量的参数,所以带有 0 的默认值是一个空序列,而不是 None 在根本不使用该选项时。它可以让你区分,是的,但它离你的意图更远。您真的要为--abc 允许多个参数吗?
  • 这和设置默认值都可以解决我的问题。我将在我的问题中包括这两个。
【解决方案3】:

不确定这是否是标准方式,但您可以将 default 参数设置为 something ,然后在 --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='*' 而不是 nargs='?' 的方法。将在几秒钟内更新我的问题。
【解决方案4】:

我正在使用它来为多处理提供一个命令行参数。指定 --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)

【讨论】:

    猜你喜欢
    • 2014-01-18
    • 2020-03-16
    • 1970-01-01
    • 2020-08-23
    • 2013-04-25
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多