标准库里的网段计算器
Python 标准库的 ipaddress 模块可以完成网段、广播、主机列表、子网拆分、地址聚合与类型判断等几乎所有子网计算,不需要安装任何第三方包。相比命令行工具,它的优势是能嵌进脚本:批量生成 VLAN 网段、校验配置、分配地址池这类工作都可以自动化。
strict 参数是主要陷阱
ip_network() 默认 strict=True,传入「主机地址 + 掩码」会直接抛 ValueError,因为它不是合法的网段写法。工程上一般用 strict=False 让它自动归位,再断言结果是否等于预期网段——这样既不会因为输入不规范而中断,又能发现真实的配置错误。
基本信息
| 常用对象 | ip_network / ip_interface / ip_address |
|---|---|
| 关键属性 | network_address、broadcast_address、netmask、hostmask、num_addresses |
| 拆分与聚合 | subnets(new_prefix=n)、collapse_addresses() |
| 严格模式 | strict=True 要求输入就是网络地址;strict=False 自动归位 |
| 判断 | in 判断归属、overlaps 判断重叠、subnet_of 判断嵌套 |
典型使用场景
- 批量生成一个 /16 下所有 /24 的清单,用于下发 VLAN 配置
- 校验规划表:检查各段是否重叠、是否落在同一父网段内
- 从地址反算网段与广播,替代手算并避免人为笔误
- 统计剩余空间:从总池中减去已用段,得到可分配清单
- 判断地址类型:私网、回环、链路本地、组播、是否全球可路由
基础计算
基础计算
import ipaddress as ip
net = ip.ip_network('192.168.1.130/27', strict=False)
print(net.network_address) # 192.168.1.128
print(net.broadcast_address) # 192.168.1.159
print(net.netmask, net.hostmask) # 255.255.255.224 0.0.0.31
print(net.num_addresses) # 32
print(len(list(net.hosts()))) # 30拆分、聚合与重叠检查
拆分、聚合与重叠检查
import ipaddress as ip
print([str(x) for x in ip.ip_network('192.168.1.0/24').subnets(new_prefix=26)])
# ['192.168.1.0/26', '192.168.1.64/26', '192.168.1.128/26', '192.168.1.192/26']
print(list(ip.collapse_addresses([ip.ip_network('192.168.0.0/24'), ip.ip_network('192.168.1.0/24')])))
# [IPv4Network('192.168.0.0/23')]
print(ip.ip_network('192.168.1.0/25').overlaps(ip.ip_network('192.168.1.128/25'))) # False常用方法速查
| 方法 / 属性 | 作用 | 注意点 |
|---|---|---|
| ip_network(..., strict=False) | 构造网段并自动归位 | strict=True 时主机地址会报错 |
| subnets(new_prefix=n) | 按更长前缀拆分 | n 必须大于当前前缀,否则报错 |
| collapse_addresses() | 合并可聚合的网段 | 只合并连续且对齐的段 |
| overlaps() | 判断两个网段是否重叠 | 规划表校验的核心方法 |
| is_private / is_global | 判断地址性质 | 链路本地、回环等 also is_private 为 True |
| hosts() | 枚举可用主机 | 大网段上枚举会耗尽内存,慎用 |
在 /8 或 /12 这类大网段上调用 list(net.hosts()) 要谨慎:那会生成上千万个对象并把内存吃满。需要遍历时应先按 /24 这类粒度拆分,或只取前若干个样本做校验。
ip_network 与 ip_interface 语义不同:前者表示一个网段,后者表示「某个 IP 在某网段内」的接口地址。用错对象会让 network_address 与输入混淆,配置生成类脚本里尤其容易出问题。