呈步 发表于 2025-6-9 15:11:05

一文读懂 Python 的 ipaddress 模块:IP 地址处理全攻略

一文读懂 Python 的 ipaddress 模块:IP 地址处理全攻略

本文聚焦于 Python 的ipaddress模块,详细介绍其在处理 IP 地址和网络相关操作中的应用。通过丰富的示例、直观的图表和对比表格,助力读者深入理解该模块,从创建各类 IP 对象,到审查对象属性、进行比较运算,再到与其他模块协同使用,全面掌握 IP 地址处理技巧。
一、ipaddress 模块概述

ipaddress模块是 Python 用于检查和操作 IP 地址的强大工具。在互联网协议从 IPv4 向 IPv6 迁移的背景下,该模块能帮助开发者轻松处理不同版本的 IP 地址和网络相关任务 。
二、创建 IP 对象

(一)IP 主机地址

使用ipaddress.ip_address()工厂函数可根据传入的值自动创建 IPv4 或 IPv6 地址。也能直接从整数创建地址,还可通过直接调用IPv4Address或IPv6Address类来强制使用特定版本 。
import ipaddress

# 使用工厂函数创建IPv4地址
ipv4_addr1 = ipaddress.ip_address('192.168.1.1')
print(ipv4_addr1)

# 使用工厂函数创建IPv6地址
ipv6_addr1 = ipaddress.ip_address('2001:db8::1')
print(ipv6_addr1)

# 从整数创建IPv4地址
ipv4_addr2 = ipaddress.ip_address(3232235777)
print(ipv4_addr2)

# 强制创建IPv6地址
ipv6_addr2 = ipaddress.IPv6Address(1)
print(ipv6_addr2)(二)定义网络

ipaddress.ip_network()工厂函数用于创建网络对象,输入字符串 “网络地址 / 网络前缀” ,也可用整数定义网络 。若要创建设置了主机位的网络对象,需传入strict=False参数 。
# 创建IPv4网络对象
ipv4_net1 = ipaddress.ip_network('192.168.1.0/24')
print(ipv4_net1)

# 创建IPv6网络对象
ipv6_net1 = ipaddress.ip_network('2001:db8::/64')
print(ipv6_net1)

# 用整数定义网络
ipv4_net2 = ipaddress.ip_network(3232235520)
print(ipv4_net2)

# 创建设置了主机位的网络对象
try:
    ipaddress.ip_network('192.168.1.1/24')
except ValueError as e:
    print(f"错误: {e}")

ipv4_net3 = ipaddress.ip_network('192.168.1.1/24', strict=False)
print(ipv4_net3)(三)主机接口

ipaddress.ip_interface()用于创建主机接口对象,将地址与特定网络关联 。同样接受整数输入,并可强制使用特定 IP 版本 。
# 创建IPv4主机接口对象
ipv4_intf1 = ipaddress.ip_interface('192.168.1.1/24')
print(ipv4_intf1)

# 创建IPv6主机接口对象
ipv6_intf1 = ipaddress.ip_interface('2001:db8::1/64')
print(ipv6_intf1)不同 IP 对象创建方式对比

对象类型创建方式示例注意事项IP 主机地址ipaddress.ip_address()工厂函数 直接调用IPv4Address/IPv6Address类ipaddress.ip_address('192.0.2.1') ipaddress.IPv6Address(1)从整数创建时,32 位值默认视为 IPv4 地址;可强制使用特定版本网络对象ipaddress.ip_network()工厂函数 直接调用IPv4Network/IPv6Network类ipaddress.ip_network('192.0.2.0/24') ipaddress.IPv4Network(3221225984)网络对象不能设置主机位,如需设置可传strict=False主机接口对象ipaddress.ip_interface()函数 直接调用IPv4Interface/IPv6Interface类ipaddress.ip_interface('192.0.2.1/24') ipaddress.IPv6Interface('2001:db8::1/96')地址部分不限于网络地址三、审查 IP 对象

(一)提取 IP 版本

通过对象的version属性可获取 IP 版本 。
ipv4_addr = ipaddress.ip_address('192.168.1.1')
ipv6_addr = ipaddress.ip_address('2001:db8::1')

print(f"IPv4地址版本: {ipv4_addr.version}")
print(f"IPv6地址版本: {ipv6_addr.version}")(二)从接口获取网络

使用接口对象的network属性可获取关联的网络对象 。
ipv4_intf = ipaddress.ip_interface('192.168.1.1/24')
ipv6_intf = ipaddress.ip_interface('2001:db8::1/64')

print(f"IPv4接口关联的网络: {ipv4_intf.network}")
print(f"IPv6接口关联的网络: {ipv6_intf.network}")(三)获取网络地址数量

通过网络对象的num_addresses属性可得知网络中独立地址的数量 。
ipv4_net = ipaddress.ip_network('192.168.1.0/24')
ipv6_net = ipaddress.ip_network('2001:db8::/64')

print(f"IPv4网络地址数量: {ipv4_net.num_addresses}")
print(f"IPv6网络地址数量: {ipv6_net.num_addresses}")(四)迭代网络上的 “可用” 地址

使用网络对象的hosts()方法可迭代网络上的可用地址 。
ipv4_net = ipaddress.ip_network('192.168.1.0/24')
for addr in ipv4_net.hosts():
    print(addr)(五)获取网络掩码和主机掩码

通过网络对象的netmask和hostmask属性可获取相应掩码 。
ipv4_net = ipaddress.ip_network('192.168.1.0/24')
ipv6_net = ipaddress.ip_network('2001:db8::/64')

print(f"IPv4网络掩码: {ipv4_net.netmask}")
print(f"IPv4主机掩码: {ipv4_net.hostmask}")
print(f"IPv6网络掩码: {ipv6_net.netmask}")
print(f"IPv6主机掩码: {ipv6_net.hostmask}")(六)展开或压缩地址

IPv6 地址可通过exploded和compressed属性进行展开或压缩,IPv4 地址虽不支持,但相关对象仍提供这些属性以保证代码兼容性 。
ipv6_addr = ipaddress.ip_address('2001:db8::1')

print(f"展开的IPv6地址: {ipv6_addr.exploded}")
print(f"压缩的IPv6地址: {ipv6_addr.compressed}")审查 IP 对象属性和方法总结

操作属性 / 方法适用对象作用提取 IP 版本versionIPv4Address、IPv6Address获取 IP 版本从接口获取网络networkIPv4Interface、IPv6Interface获取接口关联的网络对象获取网络地址数量num_addressesIPv4Network、IPv6Network获取网络中独立地址数量迭代网络可用地址hosts()IPv4Network、IPv6Network迭代网络上的可用地址获取网络掩码netmaskIPv4Network、IPv6Network获取网络掩码获取主机掩码hostmaskIPv4Network、IPv6Network获取主机掩码展开 / 压缩地址exploded、compressedIPv6Address、IPv6Network展开或压缩 IPv6 地址四、Network 作为 Address 列表

网络对象可像列表一样进行索引和成员测试 。通过索引可获取特定地址,使用成员测试语法可判断地址是否在网络中 。
ipv4_net = ipaddress.ip_network('192.168.1.0/24')
ipv6_net = ipaddress.ip_network('2001:db8::/64')

print(f"IPv4网络中第一个地址: {ipv4_net}")
print(f"IPv4网络中最后一个地址: {ipv4_net[-1]}")
print(f"IPv6网络中第一个地址: {ipv6_net}")
print(f"IPv6网络中最后一个地址: {ipv6_net[-1]}")

ipv4_addr = ipaddress.ip_address('192.168.1.1')
ipv6_addr = ipaddress.ip_address('2001:db8::1')

print(f"192.168.1.1是否在192.168.1.0/24网络中: {ipv4_addr in ipv4_net}")
print(f"2001:db8::1是否在2001:db8::/64网络中: {ipv6_addr in ipv6_net}")五、比较运算

ipaddress模块支持对 IP 地址对象进行比较,不同版本或不同类型的对象比较会引发TypeError异常 。
ipv4_addr1 = ipaddress.ip_address('192.168.1.1')
ipv4_addr2 = ipaddress.ip_address('192.168.1.2')

try:
    print(ipv4_addr1 < ipv4_addr2)

    # 不同版本比较会报错
    ipv6_addr = ipaddress.ip_address('2001:db8::1')
    print(ipv4_addr1 < ipv6_addr)
except TypeError as e:
    print(f"错误: {e}")六、将 IP 地址与其他模块一起使用

其他使用 IP 地址的模块(如socket)通常不直接接受ipaddress模块的对象,需将其转换为整数或字符串 。
import socket
import ipaddress

ipv4_addr = ipaddress.ip_address('192.168.1.1')
str_addr = str(ipv4_addr)
int_addr = int(ipv4_addr)

print(f"字符串形式的IP地址: {str_addr}")
print(f"整数形式的IP地址: {int_addr}")

# 假设使用socket模块创建TCP连接
try:
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((str_addr, 80))
    sock.close()
except socket.error as e:
    print(f"连接错误: {e}")七、实例创建失败时获取更多详细信息

使用版本无关的工厂函数创建对象时,错误会以ValueError报告。直接使用类构造函数时,会引发ipaddress.AddressValueError和ipaddress.NetmaskValueError等子类,提供更详细的错误信息 。
try:
    ipaddress.ip_address("192.168.0.256")
except ValueError as e:
    print(f"通用错误: {e}")

try:
    ipaddress.IPv4Address("192.168.0.256")
except ipaddress.AddressValueError as e:
    print(f"详细地址错误: {e}")

try:
    ipaddress.ip_network("192.168.0.1/64")
except ValueError as e:
    print(f"通用网络错误: {e}")

try:
    ipaddress.IPv4Network("192.168.0.1/64")
except ipaddress.NetmaskValueError as e:
    print(f"详细网络掩码错误: {e}")八、总结

ipaddress模块为 Python 开发者提供了处理 IP 地址和网络的便捷方式。通过创建各类 IP 对象,审查对象属性,进行比较运算,以及与其他模块协同使用,开发者能轻松应对 IP 地址相关的各种任务。在使用过程中,需注意不同 IP 版本的差异,以及对象创建和操作时可能出现的错误处理。掌握该模块的使用,有助于提升网络编程和系统管理相关任务的开发效率。
TAG:Python、ipaddress 模块、IP 地址、网络编程、IPv4、IPv6
官方文档:Python 官方文档 - ipaddress 模块,提供了最权威和详细的知识点说明,是深入学习的重要参考。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 一文读懂 Python 的 ipaddress 模块:IP 地址处理全攻略