Python 使用 argparse 多次使用不同的选项 [英] Python using diferent options multiple times with argparse

查看:25
本文介绍了Python 使用 argparse 多次使用不同的选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个自定义 Nagios 脚本,我想在其中使用与现有 Nagios 插件 check_disk 相同的方式来解析命令行参数.

在该插件中,您有一个选项参数 -C 可以Clear 当前配置并使用新参数重新开始.

摘自check_disk帮助:

check_disk -w 100 -c 50 -C -w 1000 -c 500 -p/foo -C -w 5% -c 3% -p/bar----(3)----- ---------(1)---------- --------(2)--------

检查警告/严重阈值:

  1. 对于卷 /foo 使用 1000M 和 500M 作为阈值
  2. 对于音量 /bar 使用 5% 和 3%
  3. 所有剩余的卷使用 100M 和 50M

我尝试使用 argparse 和一些参数作为 action='append',但重复的参数存储在列表中,缺少的参数不包括为无";入口.

我也尝试过使用 parse_known_args 希望停止解析第一个 unknown 参数,但我得到了一个包含所有已知参数和未知参数列表的命名空间.

我想我唯一的选择是在解析命令行参数之前使用正则表达式.

import re导入参数解析导入系统解析器 = argparse.ArgumentParser()parser.add_argument('-w', help='warning')parser.add_argument('-c', help='critical')parser.add_argument('-p', help='path')分隔符=r'-S'组 = re.split(separator, '|'.join(sys.argv[1:])))参数 = []对于 idx,enumerate(groups) 中的 group_args:args.append('')args[idx]=parser.parse_args(group_args.split('|'))

我不知道argparse是否可以处理这种情况,而无需使用正则表达式进行拆分.

或者如果这是我能找到的最佳方法.

这与多次使用同一个选项无关在 Python 的 argparse 中,因为情况不同,我有不同的可选参数,而不仅仅是一个具有多个值的选项.

在上面的例子中 (3) 没有选项 -p,(1) 和 (2) 有它.这是差异之一,也是问题之一.如果所有选项都是强制性的,那就很容易了.

解决方案

处理这个:

check_disk -w 100 -c 50 -C -w 1000 -c 500 -p/foo -C -w 5% -c 3% -p/bar

我可以想象从命名空间开始

args = argparse.Namespace(w:[None], c:[None], p:[None])args = parser.parse_args(args=args)

并定义几个自定义 Action 类.

对于 `-C` 使用一个类,将 `None` 附加到这 3 个属性中的每一个namespace['w'].append(None) 等对于 `w`、`c` 和 `p` 中的每一个,一个 Action 类,替换最后一个 `None`与用户价值.

换句话说,使用 C 参数通过推进列表来重置",然后使用其他参数来调整默认默认值.

或者以 Namespace(C=[[None, None, None]]) 开头,并在每个 'C' 后面添加一个列表.然后 'w' 将设置 namespace['C'][-1][0] 等(或使用字典列表).

I am working on a custom Nagios script in which I would like to implement parsing of command line arguments in the same way that is used on existing Nagios Plugin check_disk.

In that plugin you have an option parameter -C to Clear current config and start over with new parameters.

Extracted from check_disk help:

check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar
           ----(3)-----    ---------(1)----------    --------(2)--------

Checks warning/critical thresholds:

  1. for volume /foo use 1000M and 500M as thresholds
  2. for volume /bar use 5% and 3%
  3. All remaining volumes use 100M and 50M

I have tried with argparse and some parameter as action='append' but repeated arguments are stored in a list and missing ones are not includes as a "None" entry.

I have also tried with parse_known_args hoping to stop parsing on first unknown argument, but I get a namespace with all known arguments and a list of unknown arguments.

I guess that my only option is using regular expressions before parsing the command line arguments.

import re
import argparse
import sys

parser = argparse.ArgumentParser()
parser.add_argument('-w', help='warning')
parser.add_argument('-c', help='critical')
parser.add_argument('-p', help='path')

separator=r'-S'
groups = re.split(separator, '|'.join(sys.argv[1:])))

args = []
for idx, group_args in enumerate(groups):
   args.append('')
   args[idx]=parser.parse_args(group_args.split('|'))

I do not know if argparse can handle this kind of scenario without need to split using regular expressions.

Or if this is the best approach I can find.

This is not related with Using the same option multiple times in Python's argparse because it is not the same case, I have different optional argument not just one option with multiple values.

In example above (3) have not got option -p, (1) and (2) have it. That is one of the difference and one of the problems. If all options were mandatory, it was easy.

解决方案

To handle this:

check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar

I can imagine starting with a namespace

args = argparse.Namespace(w:[None], c:[None], p:[None])
args = parser.parse_args(args=args)

and define a couple of custom Action classes.

For `-C` use a class that appends a `None` to each of those 3 attributes
    namespace['w'].append(None), etc

For each of `w`, `c` and `p`, an Action class, that replaces the last `None`
    with the users value.  

In other words, use the C argument to 'reset' by advancing the lists, and then use the others to to adjust the default default values.

Alternatively start with a Namespace(C=[[None, None, None]]), and add append a list with each 'C'. Then 'w' would set the namespace['C'][-1][0] etc. (Or use a list of dicts).

这篇关于Python 使用 argparse 多次使用不同的选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆