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')
解决方案
我意识到我真的迟到了,但我必须为工作项目完成同样的事情。下面是我所做的一个非常简化的版本。
完整披露:这显然是 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)
示例输出:
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
显然,有些事情您可能想要解决,例如:
- 参数化您正在查找的选项的名称,以便不重复“名称”值
- 拥有一个参数字典,其中参数的数量可以变化并查找参数,而不是拥有仅适用于单个参数的 if 语句。
推荐阅读
- informatica-powercenter - 仅在 informatica SQ 的 64 个分区中的一个分区中出现低吞吐量
- python - 从索引中返回矩阵
- git - Jenkins:从不同的 BitBucket 存储库触发相同的作业
- javascript - 使用 RESTDataSource 为 GET 请求设置“参数”
- swift - SceneKit:旋转节点但定义目标角度
- c# - 如何在 C# 中退出非 void 方法
- c# - 在 Autofac 中注册第三方类,其构造函数从另一个服务中获取值
- graphql - GraphQL 不同的结果,如果不同的权限
- laravel - 在 GraphQL 中使用非默认模式
- routing - 你能让 Blazor WebAssembly 使用导航更新组件吗?