Argparse:“可选参数”下列出了必需参数吗?


229

我使用下面的简单代码来解析一些参数。请注意,其中之一是必需的。不幸的是,当用户在不提供参数的情况下运行脚本时,显示的用法/帮助文本并不表示存在一个非可选的参数,我感到非常困惑。如何获取python以指示参数不是可选的?

这是代码:

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Foo')
    parser.add_argument('-i','--input', help='Input file name', required=True)
    parser.add_argument('-o','--output', help='Output file name', default="stdout")
    args = parser.parse_args()
    print ("Input file: %s" % args.input )
    print ("Output file: %s" % args.output )

在不提供必需参数的情况下运行上述代码时,得到以下输出:

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
    -h, --help            show this help message and exit
    -i INPUT, --input INPUT
                          Input file name
    -o OUTPUT, --output OUTPUT
                          Output file name

5
在用法行中,该-i INPUT零件没有被方括号包围,这微妙地表明确实是必需的。此外,您还可以手动解释说,通过helpPARAM
海梅RGP

7
@JaimeRGP是的,但是那还不够,而且还不够突出。optional arguments所需参数的已分配组名仍然令人误解。
Acumenus

Answers:


316

-或开头的参数--通常被认为是可选的。所有其他参数都是位置参数,因此是设计所必需的(例如位置函数自变量)。可能需要可选参数,但这有点违背其设计。由于它们仍然是非位置参数的一部分,因此即使需要它们,它们仍将列在令人困惑的标题“可选参数”下。但是,用法部分缺少的方括号表明确实需要它们。

另请参阅文档

通常,argparse模块假定-f和--bar之类的标志表示可选参数,在命令行中始终可以将其省略。

注意:必需的选项通常被认为是错误的格式,因为用户期望选项是可选的,因此应尽可能避免使用。

就是说,帮助中的标头“位置参数”“可选参数”是由两个参数组生成的,参数被自动分成两个。现在,您可以“破解”并更改可选参数的名称,但是一种更为优雅的解决方案是为“必需的命名参数”(或您要调用的任何参数)创建另一个组:

parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

required named arguments:
  -i INPUT, --input INPUT
                        Input file name

我一直有同样的问题。我尝试过解决方案。它确实将参数添加到新组中,但此后我的代码似乎不起作用。任何解决方案将不胜感激。链接到我的代码- pastebin.com/PvC2aujz
扎拉尔马哈茂德

1
@ZararMahmud:您在代码的第24行中传递了空参数:parser.parse_args([])相反,请不使用parser.parse_args()任何参数来捕获sys.argv的内容。Per argparse
Devin

@poke:不错的解决方案!但这在您需要互斥组的情况下无济于事,还是我错过了任何东西?
法官


79

由于我倾向于在可选参数之前列出必需的参数,因此我通过以下方法解决了这个问题:

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--required_arg', required=True)
    optional.add_argument('--optional_arg')
    return parser.parse_args()

并输出:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
               [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  --optional_arg OPTIONAL_ARG

我可以在可选参数组中不显示“帮助”的情况下生活。


3
这是否真的迫使argparse根据需要处理任何参数?
安东尼

6
我认为添加参数时仍需要设置“必需”参数。
卡尔·罗莎

这是非常好的。
保罗·塞尚

7
@Anthony-不,您需要在add_argument中使用“ required = True”。上面的答案仅说明了参数分组。
user2275693 '18

47

从@Karl Rosaen建造

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()

并输出:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG

1
顺便说一句,有什么方法(方法)如何在_action_group不访问受保护成员的情况下获得访问权限?就我而言,我需要向已经存在的(自定义)组添加一些参数。
machin

这很棒。解决显示在第二个可选列表中的--help项。
杰里米

注意:此答案将破坏公开的API,请在下面按Bryan_D的方法检查答案
大声笑

18

再过一次,以@RalphyZ为基础

这个不会破坏公开的API。

from argparse import ArgumentParser, SUPPRESS
# Disable default help
parser = ArgumentParser(add_help=False)
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')

# Add back help 
optional.add_argument(
    '-h',
    '--help',
    action='help',
    default=SUPPRESS,
    help='show this help message and exit'
)
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')

它将显示与上面相同的内容,并且应该在将来的版本中保留下来:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  -h, --help                    show this help message and exit
  --optional_arg OPTIONAL_ARG

您能解释一下RalphyZ的答案如何破坏公开的API吗?
jeremysprofile

5
_action_groups仅供内部使用。因此,不能保证所有版本之间的兼容性。
Bryan_D
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.