最可靠方式是调用ipaddress.ip_network()验证网段,合法输入返回network实例,非法输入抛valueerror或addressvalueerror;可用network.hosts()和num_addresses计算ip范围,注意ipv4/ipv6差异及/31特例;判断归属需先转ip_address再用in,重叠用overlaps();用户输入需兼容cidr、掩码、范围三种格式,后者须用summarize_address_range()处理。

用 ipaddress.ip_network() 判定是否为合法网段
直接调用 ipaddress.ip_network() 是最可靠的验证方式,它会主动抛出异常来暴露非法输入——比如掩码越界、地址格式错误或主机位非零(如 192.168.1.5/24)。
- 合法网段:传入字符串如
"10.0.0.0/8"或"2001:db8::/32",返回IPv4Network或IPv6Network实例 - 非法情况:
ValueError(如"192.168.1.100/24"主机位非零)、AddressValueError(如"999.1.1.1/24") - 注意:默认严格模式,若想允许主机位非零(即自动归一化),加参数
strict=False,但结果仍是归一后的网络地址,不是原始输入
用 network.hosts() 和 network.num_addresses 计算可用IP范围
网段对象自带计算能力,但要注意 IPv4 和 IPv6 的行为差异,以及“可用地址”是否包含网络地址和广播地址。
-
network.num_addresses返回总地址数(含网络地址和广播地址),IPv4 中/31和/32也适用;IPv6 没有广播地址,所以全部地址都可分配 -
network.hosts()返回一个生成器,只产出**可用主机地址**(排除网络地址和广播地址),对/32返回空,对/31(RFC 3021)返回 2 个地址(IPv4 中特例) - 别用
list(network)遍历整个网段——大网段(如/16)会内存爆炸,优先用生成器或切片逻辑
用 ipaddress.ip_address() 和 network.overlaps() 做地址归属与重叠判断
单个 IP 是否落在某网段内,不能靠字符串匹配或简单数值比较,必须用模块原生方法。
- 判断归属:先用
ipaddress.ip_address("192.168.1.5")转成对象,再调用ip in network(支持in运算符) - 判断网段重叠:用
net1.overlaps(net2),比手动计算边界更可靠,尤其对 IPv6 或非 CIDR 对齐的网段(如ipaddress.ip_network("10.0.0.0/255.255.255.0", strict=False)) - 常见坑:把字符串直接跟
network比较(如"192.168.1.1" in net)会始终返回False,必须先转成ip_address对象
处理用户输入时,如何安全地兼容 CIDR、掩码、范围三种格式
真实场景中用户可能输 "192.168.1.0/24"、"192.168.1.0/255.255.255.0" 或 "192.168.1.1-192.168.1.254",ipaddress 模块只原生支持前两种。
- CIDR 和掩码格式:统一走
ipaddress.ip_network(..., strict=False),能自动处理/255.255.255.0 - 地址范围格式:需手动拆分、转
ip_address、再构造最小覆盖网段(用summarize_address_range()),例如ipaddress.summarize_address_range(ip1, ip2)返回网段生成器 - 关键提醒:
summarize_address_range()只接受同类型地址(IPv4+IPv4),且要求ip1 ,否则抛 <code>ValueError;另外它可能返回多个网段(如跨/24边界),不能假设只有一条
strict 参数的默认值,以及把字符串当 IP 对象直接参与运算——这两个点几乎每次写网络逻辑都会踩一次。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











