一文读懂 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 版本 | version |
IPv4Address 、IPv6Address |
获取 IP 版本 |
从接口获取网络 | network |
IPv4Interface 、IPv6Interface |
获取接口关联的网络对象 |
获取网络地址数量 | num_addresses |
IPv4Network 、IPv6Network |
获取网络中独立地址数量 |
迭代网络可用地址 | hosts() |
IPv4Network 、IPv6Network |
迭代网络上的可用地址 |
获取网络掩码 | netmask |
IPv4Network 、IPv6Network |
获取网络掩码 |
获取主机掩码 | hostmask |
IPv4Network 、IPv6Network |
获取主机掩码 |
展开 / 压缩地址 | exploded 、compressed |
IPv6Address 、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[1]}") print(f"IPv4网络中最后一个地址: {ipv4_net[-1]}") print(f"IPv6网络中第一个地址: {ipv6_net[1]}") 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 模块,提供了最权威和详细的知识点说明,是深入学习的重要参考。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!