如何使用Python的optparse解析合法IPv4/IPv6地址?
用Python optparse实现IPv4地址合法性校验
好问题!在optparse里实现自定义的IPv4地址验证其实很简单,核心思路是利用它支持自定义类型校验函数的特性——我们可以自己写一个函数来检查输入是否是合法的IPv4地址,然后把这个函数传给add_option的type参数,这样optparse会自动帮我们做校验,不合法时抛出错误。
方法一:利用socket模块快速验证(推荐)
Python的socket模块内置了inet_aton方法,可以直接验证IPv4地址的合法性,这是最可靠且简洁的方式,它会处理所有标准的IPv4规则(比如每个 octet 必须在0-255之间、格式为四段数字等)。
完整代码示例
import optparse import socket def validate_ipv4(option, opt_str, value): try: # 用socket的内置方法验证IPv4合法性 socket.inet_aton(value) return value except socket.error: # 验证失败时抛出optparse要求的OptionValueError raise optparse.OptionValueError(f"Invalid IPv4 address: {opt_str}") def main(): parser = optparse.OptionParser() # 你提到的整数类型选项 parser.add_option("-n", action="store", type="int", dest="number", help="Input an integer number") # 自定义IPv4校验的选项 parser.add_option("-i", action="store", type=validate_ipv4, dest="ip_address", help="Input a valid IPv4 address") options, args = parser.parse_args() # 输出解析结果 if options.number: print(f"Received integer: {options.number}") if options.ip_address: print(f"Received valid IPv4: {options.ip_address}") if __name__ == "__main__": main()
方法二:手动实现校验逻辑(适合自定义规则)
如果你需要更精细的控制(比如禁止带前导零的octet),可以手动分割IP地址并逐一检查每个部分:
自定义校验函数示例
def validate_ipv4(option, opt_str, value): parts = value.split('.') # 检查是否是4段 if len(parts) != 4: raise optparse.OptionValueError(f"Invalid IPv4 {opt_str}: must have exactly 4 octets") for part in parts: # 检查是否是纯数字 if not part.isdigit(): raise optparse.OptionValueError(f"Invalid IPv4 {opt_str}: '{part}' is not a valid number") # 检查数值范围 num = int(part) if num < 0 or num > 255: raise optparse.OptionValueError(f"Invalid IPv4 {opt_str}: '{part}' is out of range (0-255)") # 可选:禁止前导零(比如拒绝010.0.0.1这类格式) if len(part) > 1 and part.startswith('0'): raise optparse.OptionValueError(f"Invalid IPv4 {opt_str}: '{part}' has leading zeros") return value
测试效果
- 合法输入:
python your_script.py -i 127.0.0.1→ 正常解析并输出地址 - 无效输入(含非数字):
python your_script.py -i 127.0.a.1→ 自动抛出错误:error: option -i: Invalid IPv4 address: 127.0.a.1 - 无效输入(超出范围):
python your_script.py -i 256.0.0.1→ 同样抛出范围错误
内容的提问来源于stack exchange,提问作者Debiprasad Das
相关产品推荐
相关产品推荐

