找回密码
 立即注册
首页 业界区 业界 一文读懂 Python 的 ipaddress 模块:IP 地址处理全攻略 ...

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

呈步 2025-6-9 15:11:05
一文读懂 Python 的 ipaddress 模块:IP 地址处理全攻略

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

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

(一)IP 主机地址

使用ipaddress.ip_address()工厂函数可根据传入的值自动创建 IPv4 或 IPv6 地址。也能直接从整数创建地址,还可通过直接调用IPv4Address或IPv6Address类来强制使用特定版本 。
  1. import ipaddress
  2. # 使用工厂函数创建IPv4地址
  3. ipv4_addr1 = ipaddress.ip_address('192.168.1.1')
  4. print(ipv4_addr1)  
  5. # 使用工厂函数创建IPv6地址
  6. ipv6_addr1 = ipaddress.ip_address('2001:db8::1')
  7. print(ipv6_addr1)  
  8. # 从整数创建IPv4地址
  9. ipv4_addr2 = ipaddress.ip_address(3232235777)
  10. print(ipv4_addr2)  
  11. # 强制创建IPv6地址
  12. ipv6_addr2 = ipaddress.IPv6Address(1)
  13. print(ipv6_addr2)  
复制代码
(二)定义网络

ipaddress.ip_network()工厂函数用于创建网络对象,输入字符串 “网络地址 / 网络前缀” ,也可用整数定义网络 。若要创建设置了主机位的网络对象,需传入strict=False参数 。
  1. # 创建IPv4网络对象
  2. ipv4_net1 = ipaddress.ip_network('192.168.1.0/24')
  3. print(ipv4_net1)  
  4. # 创建IPv6网络对象
  5. ipv6_net1 = ipaddress.ip_network('2001:db8::/64')
  6. print(ipv6_net1)  
  7. # 用整数定义网络
  8. ipv4_net2 = ipaddress.ip_network(3232235520)
  9. print(ipv4_net2)  
  10. # 创建设置了主机位的网络对象
  11. try:
  12.     ipaddress.ip_network('192.168.1.1/24')
  13. except ValueError as e:
  14.     print(f"错误: {e}")
  15. ipv4_net3 = ipaddress.ip_network('192.168.1.1/24', strict=False)
  16. print(ipv4_net3)  
复制代码
(三)主机接口

ipaddress.ip_interface()用于创建主机接口对象,将地址与特定网络关联 。同样接受整数输入,并可强制使用特定 IP 版本 。
  1. # 创建IPv4主机接口对象
  2. ipv4_intf1 = ipaddress.ip_interface('192.168.1.1/24')
  3. print(ipv4_intf1)  
  4. # 创建IPv6主机接口对象
  5. ipv6_intf1 = ipaddress.ip_interface('2001:db8::1/64')
  6. 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 版本 。
  1. ipv4_addr = ipaddress.ip_address('192.168.1.1')
  2. ipv6_addr = ipaddress.ip_address('2001:db8::1')
  3. print(f"IPv4地址版本: {ipv4_addr.version}")
  4. print(f"IPv6地址版本: {ipv6_addr.version}")
复制代码
(二)从接口获取网络

使用接口对象的network属性可获取关联的网络对象 。
  1. ipv4_intf = ipaddress.ip_interface('192.168.1.1/24')
  2. ipv6_intf = ipaddress.ip_interface('2001:db8::1/64')
  3. print(f"IPv4接口关联的网络: {ipv4_intf.network}")
  4. print(f"IPv6接口关联的网络: {ipv6_intf.network}")
复制代码
(三)获取网络地址数量

通过网络对象的num_addresses属性可得知网络中独立地址的数量 。
  1. ipv4_net = ipaddress.ip_network('192.168.1.0/24')
  2. ipv6_net = ipaddress.ip_network('2001:db8::/64')
  3. print(f"IPv4网络地址数量: {ipv4_net.num_addresses}")
  4. print(f"IPv6网络地址数量: {ipv6_net.num_addresses}")
复制代码
(四)迭代网络上的 “可用” 地址

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

通过网络对象的netmask和hostmask属性可获取相应掩码 。
  1. ipv4_net = ipaddress.ip_network('192.168.1.0/24')
  2. ipv6_net = ipaddress.ip_network('2001:db8::/64')
  3. print(f"IPv4网络掩码: {ipv4_net.netmask}")
  4. print(f"IPv4主机掩码: {ipv4_net.hostmask}")
  5. print(f"IPv6网络掩码: {ipv6_net.netmask}")
  6. print(f"IPv6主机掩码: {ipv6_net.hostmask}")
复制代码
(六)展开或压缩地址

IPv6 地址可通过exploded和compressed属性进行展开或压缩,IPv4 地址虽不支持,但相关对象仍提供这些属性以保证代码兼容性 。
  1. ipv6_addr = ipaddress.ip_address('2001:db8::1')
  2. print(f"展开的IPv6地址: {ipv6_addr.exploded}")
  3. 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 列表

网络对象可像列表一样进行索引和成员测试 。通过索引可获取特定地址,使用成员测试语法可判断地址是否在网络中 。
  1. ipv4_net = ipaddress.ip_network('192.168.1.0/24')
  2. ipv6_net = ipaddress.ip_network('2001:db8::/64')
  3. print(f"IPv4网络中第一个地址: {ipv4_net[1]}")
  4. print(f"IPv4网络中最后一个地址: {ipv4_net[-1]}")
  5. print(f"IPv6网络中第一个地址: {ipv6_net[1]}")
  6. print(f"IPv6网络中最后一个地址: {ipv6_net[-1]}")
  7. ipv4_addr = ipaddress.ip_address('192.168.1.1')
  8. ipv6_addr = ipaddress.ip_address('2001:db8::1')
  9. print(f"192.168.1.1是否在192.168.1.0/24网络中: {ipv4_addr in ipv4_net}")
  10. print(f"2001:db8::1是否在2001:db8::/64网络中: {ipv6_addr in ipv6_net}")
复制代码
五、比较运算

ipaddress模块支持对 IP 地址对象进行比较,不同版本或不同类型的对象比较会引发TypeError异常 。
  1. ipv4_addr1 = ipaddress.ip_address('192.168.1.1')
  2. ipv4_addr2 = ipaddress.ip_address('192.168.1.2')
  3. try:
  4.     print(ipv4_addr1 < ipv4_addr2)
  5.     # 不同版本比较会报错
  6.     ipv6_addr = ipaddress.ip_address('2001:db8::1')
  7.     print(ipv4_addr1 < ipv6_addr)
  8. except TypeError as e:
  9.     print(f"错误: {e}")
复制代码
六、将 IP 地址与其他模块一起使用

其他使用 IP 地址的模块(如socket)通常不直接接受ipaddress模块的对象,需将其转换为整数或字符串 。
  1. import socket
  2. import ipaddress
  3. ipv4_addr = ipaddress.ip_address('192.168.1.1')
  4. str_addr = str(ipv4_addr)
  5. int_addr = int(ipv4_addr)
  6. print(f"字符串形式的IP地址: {str_addr}")
  7. print(f"整数形式的IP地址: {int_addr}")
  8. # 假设使用socket模块创建TCP连接
  9. try:
  10.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  11.     sock.connect((str_addr, 80))
  12.     sock.close()
  13. except socket.error as e:
  14.     print(f"连接错误: {e}")
复制代码
七、实例创建失败时获取更多详细信息

使用版本无关的工厂函数创建对象时,错误会以ValueError报告。直接使用类构造函数时,会引发ipaddress.AddressValueError和ipaddress.NetmaskValueError等子类,提供更详细的错误信息 。
  1. try:
  2.     ipaddress.ip_address("192.168.0.256")
  3. except ValueError as e:
  4.     print(f"通用错误: {e}")
  5. try:
  6.     ipaddress.IPv4Address("192.168.0.256")
  7. except ipaddress.AddressValueError as e:
  8.     print(f"详细地址错误: {e}")
  9. try:
  10.     ipaddress.ip_network("192.168.0.1/64")
  11. except ValueError as e:
  12.     print(f"通用网络错误: {e}")
  13. try:
  14.     ipaddress.IPv4Network("192.168.0.1/64")
  15. except ipaddress.NetmaskValueError as e:
  16.     print(f"详细网络掩码错误: {e}")
复制代码
八、总结

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册