argparse更改参数的定义

时间:2012-06-13 21:36:18

标签: python argparse

我按如下方式设置了我的参数解析器:

parser=argparse.ArgumentParser()
parser.add_argument('--point',help='enter a point (e.g. 2,3,4)')
parser.parse_args('--point=-2,5,6'.split())  #works
parser.parse_args('--point -2,5,6'.split())  #doesn't work :(

有没有办法告诉argparse与正则表达式r"-\d+.*"匹配的字符串不是选项而是选项的参数?

另请注意,我可以执行以下操作:

parser.add_argument('--point',nargs='*')
parser.parse_args('--point -2 5 6'.split())

但这并不是我希望它如何运作。

3 个答案:

答案 0 :(得分:2)

我认为预处理sys.argv是最简单的方法。考虑例如:

import argparse, re

parser=argparse.ArgumentParser()
parser.add_argument('--point',help='enter a point (e.g. 2,3,4)')

args = '--point -2,5,6'.split() # or sys.argv

is_list = re.compile(r'^-?[\d,.]+$')
args = ['"%s"' % x if is_list.match(x) else x for x in args]
print parser.parse_args(args)

这会返回Namespace(point='"-2,5,6"'),这应该很容易解析。

答案 1 :(得分:1)

您可以更改prefix char,以便-不再被识别为指示参数的开始。它确实看起来有点奇怪但是当负数出现在参数中时它很有用。

import argparse
parser=argparse.ArgumentParser(prefix_chars = '@')
parser.add_argument('@@point',help='enter a point (e.g. 2,3,4)')
args = parser.parse_args('@@point=-2,5,6'.split())  #works
print(args)
# Namespace(point='-2,5,6')

args = parser.parse_args('@@point -2,5,6'.split())  #work also
print(args)
# Namespace(point='-2,5,6')

答案 2 :(得分:1)

如果你不介意乱用argparse内部,argparse已经做了一些非常类似于我想做的事情。 ArgumentParser继承的其中一个类在__init__

中包含此行
import re as _re
...
self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')

所以为了让我的例子起作用,我们只需要换掉一个合适的正则表达式......

parser._negative_number_matcher = re.compile(r'^-\d+|^-\d*\.\d+')

通常我不太喜欢弄乱类的内部,因为它们以下划线为前缀(因为它依赖于实现并且容易改变) - 但是,在这种情况下,我认为它可能还可以,因为:

  • 如果argparse更改了该变量名称,它没有受到伤害,我们只是回到“--print -2,3,4”无法再次运行的情况。
  • 我想不出更好的方法来确定某些东西是否是正则表达式的数字(我想他们可以尝试转换为浮点数并捕获异常,但如果他们这样做,他们就没有变量再次命名为_negative_number_matcher,argparse仍然可以正常工作,除非在这个角落的情况下它没有做我想做的事情)