Python的argparse选择限制了打印

atx*_*atx 3 python argparse

目前我希望Python的argparse模块只打印出'1 - 65535'而不是{1,2,3,... 65535},但文档似乎没有为此提供任何方法.有什么建议?

Mar*_*ers 5

您可以通过设置formatter_class选项来更改默认设置的格式.

我将HelpFormatter类类化以改变它格式化choices值的方式.这个类正式是一个"实现细节",但我怀疑它会在更新的python版本中发生很大变化.

_metavar_formatter方法格式化{1, 2, ..., 65535}字符串,您的子类可以覆盖:

class RangeChoiceHelpFormatter(HelpFormatter):
    def _metavar_formatter(self, action, default_metavar):
         if action.metavar is not None:
             result = action.metavar
         elif action.choices is not None:
             result = '{%s .. %s}' % (min(action.choices), max(action.choices])
         else:
             result = default_metavar

          def format(tuple_size):
              if isinstance(result, tuple):
                  return result
              else:
                  return (result, ) * tuple_size
          return format
Run Code Online (Sandbox Code Playgroud)

另一种选择是不要choices参数用于如此大的范围,而是定义一个新的参数类型.

这只是一个可调用的,传递的字符串,它会引发argparse.ArgumentTypeError,TypeError或者ValueError如果字符串无法转换为目标类型,或者转换后的值,否则:

class IntRange(object):
    def __init__(self, start, stop=None):
        if stop is None:
            start, stop = 0, start
        self.start, self.stop = start, stop

    def __call__(self, value):
        value = int(value)
        if value < self.start or value >= self.stop:
            raise argparse.ArgumentTypeError('value outside of range')
        return value
Run Code Online (Sandbox Code Playgroud)

您可以将此作为参数类型使用,如下所示:

parser.add_argument('foo', type=IntRange(1, 65536))
Run Code Online (Sandbox Code Playgroud)

并调整您的帮助消息以指示可接受的值.