云南网站建设,企业信息化软件定制开发

专业提供昆明网站建设, 昆明软件开发, 云南网站建设,企业信息化软件定制开发服务免费咨询QQ932256355

博客园 首页 新随笔 联系 订阅 管理
  144 随笔 :: 4 文章 :: 3 评论 :: 914 阅读

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

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

一、ipaddress 模块概述

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

二、创建 IP 对象

(一)IP 主机地址

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

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)

(五)获取网络掩码和主机掩码

通过网络对象的netmaskhostmask属性可获取相应掩码 。

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 地址可通过explodedcompressed属性进行展开或压缩,IPv4 地址虽不支持,但相关对象仍提供这些属性以保证代码兼容性 。

ipv6_addr = ipaddress.ip_address('2001:db8::1')
print(f"展开的IPv6地址: {ipv6_addr.exploded}")
print(f"压缩的IPv6地址: {ipv6_addr.compressed}")

审查 IP 对象属性和方法总结

操作 属性 / 方法 适用对象 作用
提取 IP 版本 version IPv4AddressIPv6Address 获取 IP 版本
从接口获取网络 network IPv4InterfaceIPv6Interface 获取接口关联的网络对象
获取网络地址数量 num_addresses IPv4NetworkIPv6Network 获取网络中独立地址数量
迭代网络可用地址 hosts() IPv4NetworkIPv6Network 迭代网络上的可用地址
获取网络掩码 netmask IPv4NetworkIPv6Network 获取网络掩码
获取主机掩码 hostmask IPv4NetworkIPv6Network 获取主机掩码
展开 / 压缩地址 explodedcompressed IPv6AddressIPv6Network 展开或压缩 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.AddressValueErroripaddress.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 模块,提供了最权威和详细的知识点说明,是深入学习的重要参考。

posted on   TekinTian  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示