【问题标题】:Python argparse value range help message appearancePython argparse 值范围帮助消息外观
【发布时间】:2014-10-07 08:43:12
【问题描述】:

我有一个程序的参数是 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)

【问题讨论】:

  • 你能发布你的代码示例吗?
  • API 没有任何建议,可能不是使用选择,您可以实现自己的检查。
  • 您可以尝试查看 argparse.ArgumentDefaultsHelpFormatter,我自己没有使用过,但它可能会提供您需要的自定义类型。
  • 是的,我正在考虑简单地放弃内置检查并运行我自己的检查,但如果我能将它保留在 argparse 中会很好......哦,好吧。

标签: python range argparse


【解决方案1】:

使用add_argument()metavar parameter

例如:

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)

测试:

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

结果

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.

【讨论】:

【解决方案2】:

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

#!/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

测试一下:

~: 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.

【讨论】:

  • 我会自定义 type 而不是 action
【解决方案3】:

使用自定义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()

制作:

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

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

type=partial(range_type, min=10, max=90)

【讨论】:

    【解决方案4】:

    您可以通过以下几种方式来代替

    def parseCommandArgs():
        parser = argparse.ArgumentParser()
        parser.add_argument('-i', dest='myDest', choices=range(1,101), type=int, required=True, metavar='INT[1,100]', help='my help message')
        return parser.parse_args()
    

    您也可以改用action,我强烈推荐它,因为它允许更多自定义

    def verify():
        class Validity(argparse.Action):
            def __call__(self, parser, namespace, values, option_string=None):
                if values < 1 or values > 100:
                    # do something
                    pass
        return Validity
    
    def parseCommandArgs():
        parser = argparse.ArgumentParser()
        parser.add_argument('-i', dest='myDest', required=True, metavar='INT[1,100]', help='my help message', action=verify())
        return parser.parse_args()
    

    【讨论】:

      【解决方案5】:

      我为此编写了一个库:argparse-range

      >>> from argparse import ArgumentParser
      >>> from argparse_range import range_action
      >>> parser = ArgumentParser()
      >>> parser.add_argument("rangedarg", action=range_action(0, 10), help="An argument")
      >>> args = parser.parse_args(["0"])
      >>> args.rangedarg
      0
      >>> parser.parse_args(["20"])
      Traceback (most recent call last):
          ....
      argparse.ArgumentTypeError: Invalid choice: 20 (must be in range 0..=10)
      

      帮助文本是透明添加的:

      foo.py --help
      
      usage: foo.py [-h] rangedarg
      
      positional arguments:
        rangedarg   An argument (must be in range 0..=10)
      
      optional arguments:
        -h, --help  show this help message and exit
      

      其他功能包括:

      • 与默认的 argparse 处理一致地处理 defaultmetavarnargs
      • 类型推断,使用 type 参数显式覆盖

      【讨论】:

      • 当链接到您自己的网站或内容(或您附属的内容)时,您must disclose your affiliation in the answer 以免被视为垃圾邮件。根据 Stack Exchange 政策,在您的用户名中包含与 URL 相同的文本或在您的个人资料中提及它不被视为充分披露。
      猜你喜欢
      • 2013-04-28
      • 2015-07-26
      • 2016-06-21
      • 1970-01-01
      • 2012-08-17
      • 2021-09-16
      • 1970-01-01
      • 2018-10-05
      • 2013-09-10
      相关资源
      最近更新 更多