Argparse:带有一个或两个参数的选项

Bar*_*ara 6 python argparse

我想要一个带有一个或两个参数的选项,特别是时间戳和可选的容差。

我知道nargs='+'如果我得到两个以上的值,我应该使用并出错,这就是我正在做的事情。

我也在使用metavar=('timestamp', 'tolerance')所以可以命名这两个值。

但是,帮助消息仍然如下所示:
usage: foo.py [-h] [-t timestamp [tolerance ...]]
这错误地暗示-t可以采用两个以上的参数。

我怎样才能让它说出来[-t timestamp [tolerance]]?我的实际代码如下:

import argparse
import sys

parser = argparse.ArgumentParser()
parser.add_argument('-t', '--timestamp', nargs='+', metavar=('timestamp', 'tolerance'))
args = parser.parse_args()
if args.timestamp and len(args.timestamp) > 2:
    sys.exit('Argument --timestamp takes one or two values')
Run Code Online (Sandbox Code Playgroud)

cur*_*rob 0

我意识到我在这方面确实迟到了,但我必须为工作项目完成同样的事情。下面是我所做的一个非常简化的版本。

全面披露:这显然是 hacky,因为它依赖于私有函数;这是我看到的唯一方法,因为似乎没有内置支持。我的解决方案是一个应用程序的一部分,该应用程序被打包为包含我需要的特定版本的 python (3.x)(当我访问私有 API 来完成此操作时),并且我的项目具有重要的自动化测试,以捕获未来的任何损坏。你被警告了。

import argparse
import re as _re

class CustomParser(argparse.ArgumentParser):

    def _match_argument(self, action, arg_strings_pattern):
        if action.dest == 'name':
            # Account for flexible number of arguments. The pattern is copied from the parent class'
            # _get_nargs_pattern() function. 
            narg_pattern = '(-*A{1,2})'
            match = _re.match(narg_pattern , arg_strings_pattern)

            if match:
                return len(match.group(1))
            else:
                raise argparse.ArgumentError(action, "expected {} or {} arguments".format(1, 2))
        else:
            return super()._match_argument(action, arg_strings_pattern)

if __name__ == '__main__':
    parser = CustomParser("Flexible argument number test")
    # nargs must be 2 so that the help output properly formats the metavar argument.
    # Notice that I added '[]' around the optional argument to be consistent with argparse.
    parser.add_argument("--name", nargs=2, metavar=("FIRST", "[LAST]"),
                        help="Your name: FIRST LAST. The last name is optional.")

    args = parser.parse_args()
    print(args)
Run Code Online (Sandbox Code Playgroud)

输出示例:

SCRIPT --help
usage: Flexible argument number test [-h] [--name FIRST [LAST]]

optional arguments:
  -h, --help           show this help message and exit
  --name FIRST [LAST]  Your name: FIRST LAST. The last name is optional.

SCRIPT --name John
Namespace(name=['John'])

SCRIPT --name John Smith
Namespace(name=['John', 'Smith'])

SCRIPT --name
usage: Flexible argument number test [-h] [--name FIRST [LAST]]
Flexible argument number test: error: argument --name: expected 1 or 2 arguments
Run Code Online (Sandbox Code Playgroud)

显然,您可能想要解决一些问题,例如:

  • 参数化您正在查找的选项的名称,以便“名称”值不重复
  • 拥有一个参数字典,其中参数数量可以变化并查找参数,而不是使用仅适用于单个参数的 if 语句。