命令帮助(通过-h),其中argparse是范围检查输入端口号

Law*_*vil 5 python port argparse python-3.x

argparse用来解析python3程序的输入。最近有人要求我对一些数字输入进行范围检查,这似乎是个好主意。Argparse可以做到这一点。

数字输入是端口号,通常在0-65535范围内,因此我将parse命令行更改为:

import argparse
cmd_parser = argparse.ArgumentParser()
cmd_parser = add_argument('-p', help='Port number to connect to', dest='cmd_port', default=1234, type=int, choices=range(0,65536))
cmd_parser.parse_args(['-h'])
Run Code Online (Sandbox Code Playgroud)

但是,现在,当我请求帮助时,我充满了argparse中所有可能的值。例如。

optional arguments:
    -h, --help            show this help message and exit
    -p {0,1,2,3,4,5,6,7,8,9,10,11,12,13 ...
    65478,65479,65480,65481,65482,65483,65484,65485,65486,65487,65488,65489,
    65490,65491,65492,65493,65494,65495,65496,65497,65498,65499,65500,65501,
    65502,65503,65504,65505,65506,65507,65508,65509,65510,65511,65512,65513,
    65514,65515,65516,65517,65518,65519,65520,65521,65522,65523,65524,65525,
    65526,65527,65528,65529,65530,65531,65532,65533,65534,65535}
                    Port number to connect to
...
Run Code Online (Sandbox Code Playgroud)

它列出了该范围内的每个端口。有没有办法截断它或使其实现范围(0-65535)或使其使用省略号或其他使其更漂亮的方法?我唯一的选择是使用if语句显式范围检查我的输入吗?

我一直在搜索这个,但在查找人们使用argparse和指定选择的示例时遇到了麻烦。我还查看了有关argparse的文档,但没有发现任何有用的信息。 https://docs.python.org/2/library/argparse.html

are*_*ewm 5

使用自定义操作...

import argparse

class PortAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if not 0 < values < 2**16:
            raise argparse.ArgumentError(self, "port numbers must be between 0 and 2**16")
        setattr(namespace, self.dest, values)

cmd_parser = argparse.ArgumentParser()
cmd_parser.add_argument('-p',
                        help='Port number to connect to',
                        dest='cmd_port',
                        default=1234,
                        type=int,
                        action=PortAction,
                        metavar="{0..65535}")
Run Code Online (Sandbox Code Playgroud)

无效的端口号将根据引发的 ArgumentError 显示错误消息。如果输入值 65536,将打印以下行:

error: argument -p: port numbers must be between 0 and 2**16
Run Code Online (Sandbox Code Playgroud)

将根据显示的元变量打印用法和帮助消息


Mar*_*ler 3

只需使用intas输入add_argument,并手动验证它是否在允许的范围内。或者,使用您自己的类型,它具有为您执行检查的构造函数和__int__隐式转换的方法:

class portnumber:
    def __init__(self, string):
        self._val = int(string)
        if (not self._val > 0) or (not self.val < 2**16):
            raise argparse.ArgumentTypeError("port numbers must be integers between 0 and 2**16")
    def __int__(self):
        return self._val

...

parser.add_argument("-p",type=portnumber)
Run Code Online (Sandbox Code Playgroud)