VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 一文读懂 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 模块,提供了最权威和详细的知识点说明,是深入学习的重要参考。

https://www.cnblogs.com/tekin/p/18726870/python-ipaddress


相关教程