Python argparse: 可选的两个值参数

3

你好
我一直在尝试设置一个参数,当包含在命令行中时,将消耗正好两个参数;当未提供时,将默认为包含两个值的列表。到目前为止,我还没有找到实现这一点的方法。以下是我的代码:

_version="1.0.0"
_parser = argparse.ArgumentParser(description='Statmon: expandable 
server metrics retriever', usage="""
statmon.py [-a COUNT SECS] [-c CONFIG] [-o [FILE]] MODULE [PARAM ...]
statmon.py -? [-c CONFIG] MODULE
statmon.py -v""")
_parser.add_argument('-?', '--show', dest='show', default=False, action='store_true',
                     help='Request to show the metrics return by a statistics module.')
_parser.add_argument('-a', '--avg', dest='avg_ms', default=[1, 0], action='store', type=int, nargs='*',
                     help='Asks to display the average of COUNT samples within SECS time. Default one sample.')
_parser.add_argument('-c', '--conf', dest='config', default="/etc/statmon.conf", action='store', type=str,
                     nargs='+', help='Define the configuration file. Default is /etc/statmon.conf.')
_parser.add_argument('-o', '--outfile', dest='outfile', default=None, const=None, action='store', type=str,
                     nargs='?', help='Define the out file to write the stats. If not provided will biuld it.')
_parser.add_argument('-v', '--version', dest='ver', default=False, action='store_true',
                     help='Shows version of the command.')
_parser.add_argument('module', default=[], action='store', type=str, nargs='*',
                     help="The module that we should pull the metrics from and its parameters.")
_args = _parser.parse_args()
if _args.ver:
    print("{0}: {1}".format(_parser.description, _version))
    exit(0)

我的问题是与选项“-a”有关。 如果提供了它,我希望从命令行获取接下来的两个元素并将其清除以供其他选项使用。 目前我没有得到错误。 但是,如果我包含它,它将消耗命令行中超过两个元素。请参见以下示例:

$ python statmon.py cpu
Option -a: [1, 0]
{"USER": 0.0, "NICE": 0.0, "SYS": 0.0, "IDLE": 0.0}

现在提供以下选项:
$ python statmon.py -a 10 10 cpu
usage:
statmon.py [-a COUNT SECS] [-c CONFIG] [-o [FILE]] MODULE [PARAM ...]
statmon.py -? [-c CONFIG] MODULE
statmon.py -v
statmon.py: error: argument -a/--avg: invalid int value: 'cpu'

我的问题是如何告诉argparse我有一个可选参数,该参数仅使用命令行的两个元素,且只能使用两个元素? 我需要将默认值[1, 0]填充。如果不可能,我将不得不定义两个参数“-C”和“-S”,但我希望避免这样做。我还希望避免定义一个新参数“-m”来定义模块。我更喜欢它是命令行的参数而不是选项。
感谢任何帮助。

2
nargs=2 而不是星号是否有效? argparse 按位置解析,而不是按值解析。 因此,当您在可选的 nargs 变量后面有一个 '*' 位置时,第一个变量会贪婪地获取尽可能多的参数。 毕竟,星号位置与 []['a'] 一样开心。 - hpaulj
module 必须是 '*' 吗?如果不是可选的,请保留默认值为必需。或者使用 '+' 如果您想提供多个选项。然后解析器将为此操作保留最后一个字符串。argparse 允许必需的可选项和可选位置参数,但是——如果您不混合这些概念,对您和用户来说会更简单。 - hpaulj
1个回答

0
因为你设定了nargs='*',所以接下来的内容是:
python statmon.py -a 10 10 cpu

将被解释为向avg_ms传递3个参数:[10, 10, 'cpu'],但由于cpu不是有效的整数,argparse不允许它,这就是你看到这个错误的原因:

error: argument -a/--avg: invalid int value: 'cpu'

你想要的是:
python a.py -a 3 4 -- cpu

在这种情况下,cpu 被分配给 module 而不是 avg_ms
但正如 @hpaulj 所提到的,只需要使用 nargs=2,然后这将起作用:
python a.py -a 3 4 cpu

感谢@MondKin和hpaulj。我曾尝试定义nargs='2',但是出现了错误。我已更改为nargs=2,现在有一个可选参数,可以消耗恰好2个元素。因此,解决方法是使用nargs=2,而不是nargs='*'或nargs='2'。现在它可以正常工作了。还有,我之前定义的'-- cpu'选项也可以工作。但是,我将其切换为nargs=2,这样就可以按照我的预期工作了。感谢大家。 - Luis Ramirez
有人在argparse的bug/issues上问,它是否接受nargs='2'nargs=2。https://bugs.python.org/issue32474(已关闭) - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接