3

我设置我的参数解析器如下:

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())

但这并不是我真正想要的工作方式。

4

3 回答 3

3

我认为预处理 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"')应该很容易解析。

于 2012-06-14T14:18:47.060 回答
1

您可以更改前缀 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')
于 2012-06-13T21:41:34.277 回答
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 仍然可以正常工作,除非在这种极端情况下它没有做我想要的)
于 2012-06-14T13:16:58.010 回答