Python argparse值范围帮助消息外观

DJM*_*y12 7 python range argparse

我有一个参数是一个1-100的整数的程序,我只是不喜欢它在使用argparse时显示在-h帮助消息中的方式(它字面上列出0,1,2,3,4 ,5,......等)

有没有办法改变这个或用另一种方式代表它?

谢谢

编辑:

以下是那些询问的人的代码:

norse = parser.add_argument_group('Norse')
norse.add_argument('-n', '--norse', required=False, help='Run the Norse IPViking scan.', action='store_true')
norse.add_argument('--threshold', required=False, type=int, choices=range(0,101), help='Threshold (0-100) denoting at what threat level to provide additional data on an IP \
                        address. Default is 49.', default=49)
Run Code Online (Sandbox Code Playgroud)

Xin*_*Yin 16

使用metavar参数add_argument().

例如:

norse = parser.add_argument_group('Norse')
norse.add_argument('-n', '--norse', required=False, help='Run the Norse IPViking scan.', action='store_true')
norse.add_argument('--threshold', required=False, type=int, choices=range(0,101),
                   metavar="[0-100]", 
                   help='Threshold (0-100) denoting at what threat level to provide additional data on an IP \
                        address. Default is 49.', default=49)
Run Code Online (Sandbox Code Playgroud)

测试:

from argparse import ArgumentParser

norse = ArgumentParser()

norse.add_argument('-n', '--norse', required=False, help='Run the Norse IPViking scan.', action='store_true')
norse.add_argument('--threshold', required=False, type=int, choices=range(0,101), metavar="[0-100]", help='Threshold (0-100) denoting at what threat level to provide additional data on an IP address. Default is 49.', default=49)


norse.print_help()
Run Code Online (Sandbox Code Playgroud)

结果

usage: -c [-h] [-n] [--threshold [0-100]]

optional arguments:
  -h, --help           show this help message and exit
  -n, --norse          Run the Norse IPViking scan.
  --threshold [0-100]  Threshold (0-100) denoting at what threat level to
                       provide additional data on an IP address. Default is
                       49.
Run Code Online (Sandbox Code Playgroud)

  • `metavar`适用于`usage`和`help`.它对错误消息没有帮助.更多相关信息,请访问http://bugs.python.org/issue16418和http://bugs.python.org/issue16468 (5认同)

小智 7

您可以自定义操作,例如:

#!/usr/bin/env python
import argparse


class Range(argparse.Action):
    def __init__(self, minimum=None, maximum=None, *args, **kwargs):
        self.min = minimum
        self.max = maximum
        kwargs["metavar"] = "[%d-%d]" % (self.min, self.max)
        super(Range, self).__init__(*args, **kwargs)

    def __call__(self, parser, namespace, value, option_string=None):
        if not (self.min <= value <= self.max):
            msg = 'invalid choice: %r (choose from [%d-%d])' % \
                (value, self.min, self.max)
            raise argparse.ArgumentError(self, msg)
        setattr(namespace, self.dest, value)


norse = argparse.ArgumentParser('Norse')
norse.add_argument('--threshold', required=False, type=int, min=0, max=100,
                   action=Range,
                   help='Threshold [%(min)d-%(max)d] denoting at what threat \
                         level to provide additional data on an IP address. \
                         Default is %(default)s.', default=49)
args = norse.parse_args()
print args
Run Code Online (Sandbox Code Playgroud)

测试一下:

~: user$ ./test.py --threshold 10
Namespace(threshold=10)
~: user$ ./test.py --threshold -1
usage: Norse [-h] [--threshold [0-100]]
Norse: error: argument --threshold: invalid choice: -1 (choose from [0-100])
~: user$ ./test.py -h
usage: Norse [-h] [--threshold [0-100]]

optional arguments:
  -h, --help           show this help message and exit
  --threshold [0-100]  Threshold [0-100] denoting at what threat level to
                       provide additional data on an IP address. Default is
                       49.
Run Code Online (Sandbox Code Playgroud)

  • 我会自定义 `type` 而不是 `action`。 (2认同)

hpa*_*ulj 6

使用自定义type,可以更轻松地控制错误消息(通过ArgumentTypeError)。我仍然需要metavar控制使用显示。

import argparse

def range_type(astr, min=0, max=101):
    value = int(astr)
    if min<= value <= max:
        return value
    else:
        raise argparse.ArgumentTypeError('value not in range %s-%s'%(min,max))

parser = argparse.ArgumentParser()
norse = parser.add_argument_group('Norse')
...
norse.add_argument('--range', type=range_type, 
    help='Value in range: Default is %(default)s.',
    default=49, metavar='[0-101]')
parser.print_help()
print parser.parse_args()
Run Code Online (Sandbox Code Playgroud)

生产:

2244:~/mypy$ python2.7 stack25295487.py --ran 102
usage: stack25295487.py [-h] [-n] [--threshold [0:101]] [--range [0-101]]

optional arguments:
  -h, --help           show this help message and exit

Norse:
  ...
  --range [0-101]      Value in range: Default is 49.
usage: stack25295487.py [-h] [-n] [--threshold [0:101]] [--range [0-101]]
stack25295487.py: error: argument --range: value not in range 0-101
Run Code Online (Sandbox Code Playgroud)

我可以用functools.partial来自定义范围值:

type=partial(range_type, min=10, max=90)
Run Code Online (Sandbox Code Playgroud)