ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Python ipaddress 模块详解:IPv4/IPv6 地址、网络与接口的创建、检查与运算

2026/9/8 20:39:26 拓冰建站 浏览量
Python ipaddress 模块详解:IPv4/IPv6 地址、网络与接口的创建、检查与运算 Python ipaddress 模块详解IPv4/IPv6 地址、网络与接口的创建、检查与运算【免费下载链接】cpythonThe Python programming language项目地址: https://gitcode.com/GitHub_Trending/cp/cpython本篇技术指南基于 CPython 标准库 Lib/ipaddress.py 及其官方 API 参考 Doc/library/ipaddress.rst系统讲解ipaddress模块的全部能力用工厂函数便捷创建对象、用 IPv4/IPv6 地址/网络/接口对象做子网归属判定、主机遍历、掩码换算、子网切分与聚合以及地址文本校验与反向 DNS 生成等。读完本文你将掌握一套既兼容 IPv4 又兼容 IPv6 的纯 Python 地址编程范式可直接用于防火墙规则判定、配置校验、DHCP 地址池计算、安全扫描与日志归并等真实场景。配套的入门导读可参考 Doc/howto/ipaddress.rst面向不熟悉 IP 网络术语的读者本文则为完整 API 参考。模块定位创建、操作与检查的三大对象模型ipaddress自 Python 3.3 起加入标准库见 Doc/library/ipaddress.rst提供对 IPv4 与 IPv6 地址、网络的**创建create、操作manipulate与运算operate**能力。常见的典型任务包括检查两台主机是否位于同一子网、遍历某个子网内的全部主机、判断一段字符串是否为合法的 IP 地址或网络定义等。模块源码是一个纯 Python 实现、零外部依赖的单文件Lib/ipaddress.py约 2400 行其开头声明为 A fast, lightweight IPv4/IPv6 manipulation library in Python。从源码结构Lib/ipaddress.py可以梳理出清晰的继承层级异常层AddressValueError(ValueError)、NetmaskValueError(ValueError)第 17、21 行用于把“地址格式错误”与“掩码格式错误”区分开。地址层_BaseAddress→IPv4AddressLib/ipaddress.py与IPv6AddressLib/ipaddress.py。网络层_BaseNetwork→IPv4NetworkLib/ipaddress.py与IPv6NetworkLib/ipaddress.py。接口层IPv4Interface继承IPv4AddressLib/ipaddress.py与IPv6Interface继承IPv6AddressLib/ipaddress.py相当于“带网络信息的地址”。一个值得注意的设计意图是IPv4Address与IPv6Address共享大量公共属性IPv6 特有语义的属性在 IPv4 对象上也会以合理方式实现从而让“一段代码同时正确处理两个 IP 版本”成为可能。所有地址、网络、接口对象都是**可哈希hashable**的可直接用作字典键或放入集合。便捷工厂函数模块提供三个工厂函数自动依据输入判定应返回 IPv4 还是 IPv6 对象。从源码看Lib/ipaddress.py它们的实现模式一致先尝试用对应的 IPv4 构造器捕获AddressValueError/NetmaskValueError后换 IPv6 构造器再试两者都失败则抛出合并后的ValueError。 import ipaddress ipaddress.ip_address(192.168.0.1) IPv4Address(192.168.0.1) ipaddress.ip_address(2001:db8::) IPv6Address(2001:db8::)ip_address(address)返回IPv4Address或IPv6Address。地址可以是字符串或整数小于2**32的整数默认按 IPv4 处理非法输入抛ValueError。ip_network(address, strictTrue)返回IPv4Network或IPv6Network。strict参数原样透传给对应网络构造器若输入不合法或网络带主机位且strictTrue抛ValueError。 ipaddress.ip_network(192.168.0.0/28) IPv4Network(192.168.0.0/28)ip_interface(address)返回IPv4Interface或IPv6Interface用于描述“位于某个网络上的一个接口地址”。这些便利函数的共同代价是因为函数不知道调用者本意是 IPv4 还是 IPv6 格式失败时的报错信息只能给出笼统描述。需要更精确的错误信息时应当直接调用对应版本的具体类构造器详见下文“自定义异常”一节这正是AddressValueError、NetmaskValueError存在的意义。IP 地址对象合法输入形式IPv4Address(address)见 Lib/ipaddress.py接受三种形式的输入非法输入抛AddressValueError十进制点分字符串四个取值 0–255 的十进制整数用点分隔如192.168.0.1每个整数代表地址中的一个字节octet。不允许前导零以免与八进制记法混淆详见下方版本说明可放入 32 位的整数长度 4 的bytes打包对象最高有效字节在前。 ipaddress.IPv4Address(192.168.0.1) IPv4Address(192.168.0.1) ipaddress.IPv4Address(3232235521) IPv4Address(192.168.0.1) ipaddress.IPv4Address(b\xC0\xA8\x00\x01) IPv4Address(192.168.0.1)关于前导零的演进史值得特别注意3.8 之前曾容忍前导零包括形似八进制的歧义写法3.9.5 起前导零一律视为错误IPv4 字符串的解析严格程度与 glibc 的socket.inet_pton保持一致。IPv6Address(address)见 Lib/ipaddress.py接受三种形式非法输入抛AddressValueError字符串八组各 16 bit 的十六进制组以冒号分隔exploded全展开记法或采用 RFC 4291 定义的多种压缩compressed简写规则如0000:0000:0000:0000:0000:0abc:0007:0def可压缩为::abc:7:def。字符串可选携带作用域区 ID 后缀%scope_id见 RFC 4007区 ID 必须非空且不能含%例如fe80::1234%1表示本节点第一条链路上的fe80::1234可放入 128 位的整数长度 16 的bytes打包对象大端序。 ipaddress.IPv6Address(2001:db8::1000) IPv6Address(2001:db8::1000) ipaddress.IPv6Address(ff02::5678%1) IPv6Address(ff02::5678%1)通用属性IPv4/IPv6 共用属性说明version版本号IPv4 为4IPv6 为6自 3.14 起同时以类属性形式暴露max_prefixlen地址总位数IPv4 为32IPv6 为128自 3.14 起同时以类属性形式暴露前缀即决定地址是否属于某网络时被比较的“高位位数”compressed/exploded地址的字符串表示。IPv4 没有针对零字节的简写记法故两属性恒等于str(addr)同时暴露二者是为了让显示代码可统一处理两种版本packed二进制表示IPv4 为 4 字节、IPv6 为 16 字节的bytes最高有效字节在前reverse_pointer反向 DNS PTR 记录名仅是可用于 PTR 查询的名字不是解析出的主机名自 3.5 起提供is_multicast是否多播保留地址IPv4 见 RFC 3171IPv6 见 RFC 2373is_private按 IANA 特殊地址注册表判定是否“全局不可达”is_global与is_private相反is_unspecified是否未指定地址IPv4 见 RFC 5735IPv6 见 RFC 2373is_reserved是否 IETF 保留地址。IPv4 仅指240.0.0.0/4保留块IPv6 指地址空间中Reserved by IETF的全部地址。注意 IPv6 的fec0::/10旧 Site-Local不在其中参见is_site_local与 RFC 3879is_loopback是否回环地址IPv4 见 RFC 3330IPv6 见 RFC 2373is_link_local是否链路本地保留地址RFC 3927ipv6_mapped返回表示“IPv4 映射的 IPv6 地址”的IPv4Address对象RFC 4291自 3.13 起提供关于is_private/is_global的语义有两点官方明示的例外共享地址空间100.64.0.0/10上两者都为False其余地址上两者恰好相反对 IPv4-mapped IPv6 地址其判定由底层 IPv4 语义决定恒满足address.is_private address.ipv4_mapped.is_privateis_global同理。3.13 版本对is_private做过一次修正同时影响is_global修正了一批误判IPv4192.0.0.0/24视为私有时段从原来的仅192.0.0.0/29扩展为整段但192.0.0.9/32与192.0.0.10/32例外192.0.0.9即任播地址IPv664:ff9b:1::/48、2002::/16视为私有2001::/23整体视为私有但其中2001:1::1/128、2001:1::2/128、2001:3::/32、2001:4:112::/48、2001:20::/28、2001:30::/28例外不视为私有。从实现上可以印证上述常量直接编码在源码的_IPv6Constants._private_networks与_private_networks_exceptions两个列表中Lib/ipaddress.py网络对象的is_private则要求网络地址与广播地址同时命中私有区间、且同时不属于例外区间Lib/ipaddress.py。其反向指针、loopback、multicast 等输出示例 ipaddress.ip_address(127.0.0.1).reverse_pointer 1.0.0.127.in-addr.arpa ipaddress.ip_address(2001:db8::1).reverse_pointer 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpaIPv6 特有属性is_site_local是否站点本地保留地址。站点本地地址空间已被 RFC 3879 废弃判断是否属于 RFC 4193 的唯一本地地址应改用is_private。ipv4_mapped对位于::FFFF:0:0/96RFC 4291的 IPv4-mapped 地址返回内嵌的 IPv4 地址其余地址返回None。scope_idRFC 4007 作用域地址的区 ID字符串形式未指定时返回None。test_ipaddress.py中有专门针对 IPv6 scoped 地址比较与字符串化的测试Lib/test/test_ipaddress.py。sixtofour对2002::/16内的 6to4 地址RFC 3056返回内嵌 IPv4 地址否则None。teredo对2001::/32内的 Teredo 地址RFC 4380返回内嵌的(server, client)地址对否则None。字符串与整数互转与socket等网络接口互操作时需用内建str()/int()转换 str(ipaddress.IPv4Address(192.168.0.1)) 192.168.0.1 int(ipaddress.IPv4Address(192.168.0.1)) 3232235521 str(ipaddress.IPv6Address(::1)) ::1 int(ipaddress.IPv6Address(::1)) 1注意IPv6 作用域地址转整数时会丢弃%scope_id。反向包装可由v4_int_to_packed/v6_int_to_packed完成见模块级函数一节。地址运算符比较运算符只能在同版本对象间使用IPv4 对 IPv4IPv6 对 IPv6。带不同 scope zone ID 的相同 IPv6 地址不相等 IPv4Address(127.0.0.2) IPv4Address(127.0.0.1) True IPv4Address(127.0.0.2) IPv4Address(127.0.0.1) False IPv6Address(fe80::1234) IPv6Address(fe80::1234%1) False IPv6Address(fe80::1234%1) ! IPv6Address(fe80::1234%2) True算术运算符地址支持整数加减越界时抛AddressValueError IPv4Address(127.0.0.2) 3 IPv4Address(127.0.0.5) IPv4Address(127.0.0.2) - 3 IPv4Address(126.255.255.255) IPv4Address(255.255.255.255) 1 Traceback (most recent call last): ... ipaddress.AddressValueError: 4294967296 ( 2**32) is not permitted as an IPv4 address自定义格式化__format__自 3.9 起地址对象支持format()、str.format()与 f-string 的格式化协议。格式符fmt取值如下s默认等价于str()、b零填充二进制串、X/x大小写十六进制、nIPv4 等价于bIPv6 等价于x。二进制与十六进制形式还支持#前缀符与_千分位分组符。 format(ipaddress.IPv4Address(192.168.0.1)) 192.168.0.1 {:#b}.format(ipaddress.IPv4Address(192.168.0.1)) 0b11000000101010000000000000000001 f{ipaddress.IPv6Address(2001:db8::1000):s} 2001:db8::1000 format(ipaddress.IPv6Address(2001:db8::1000), _X) 2001_0DB8_0000_0000_0000_0000_0000_1000 {:#_n}.format(ipaddress.IPv6Address(2001:db8::1000)) 0x2001_0db8_0000_0000_0000_0000_0000_1000test_format在两个版本的地址测试类中均有对应覆盖Lib/test/test_ipaddress.py、Lib/test/test_ipaddress.py。IP 网络对象IPv4Network/IPv6Network用于定义并检查 IP 网段。一个网络定义由**掩码mask与网络地址network address**组成二者共同划定一段区间区间内任一地址与掩码做“按位与binary AND”后都等于网络地址。例如掩码255.255.255.0、网络地址192.168.1.0的网络包含192.168.1.0至192.168.1.255闭区间内全部地址。网络对象继承地址对象的全部属性version、is_*系列等且这些布尔属性“对整个网络成立”当且仅当网络地址与广播地址同时成立。地址对象与网络对象均为可哈希对象。前缀、网络掩码与主机掩码的换算三种等价的掩码记法贯穿本模块全部 API前缀prefix/nbits表示掩码高位置 1 的位数。IPv4 的/24等价于网络掩码255.255.255.0IPv6 等价于ffff:ff00::网络掩码net mask高位连续置 1 的地址形式主机掩码host mask网络掩码的逻辑反常用于思科访问控制列表IPv4 中/24的主机掩码为0.0.0.255。构造形式与strict语义IPv4Network(address, strictTrue)的address可以是以下四种“IP 地址 可选掩码”的字符串以/分隔掩码要么是单个数字即前缀要么是点分 IPv4 字符串——后者若首字段非零按网络掩码解释若首字段为零则按主机掩码解释唯一例外是全零掩码按网络掩码处理不带掩码时默认/32。因此下面三种写法等价192.168.1.0/24 192.168.1.0/255.255.255.0 192.168.1.0/0.0.0.255可放入 32 位的整数等价于网络地址为该整数、掩码/32的单地址网络长度 4 的大端bytes解释同整数形式二元组(地址描述, 掩码)3.5 起支持地址描述可以是字符串、32 位整数、4 字节打包整数或现成的IPv4Address对象掩码是前缀长度整数如24或前缀掩码字符串如255.255.255.0。地址非法抛AddressValueError掩码非法抛NetmaskValueError。strictTrue时若所给地址带主机位则抛ValueError否则主机位会被掩掉以得到规范网络地址。例如ip_network(192.168.1.1/24)在默认strictTrue下会报错需显式strictFalse或改用接口对象。未另行说明时接受其它网络/地址对象的网络方法在参数 IP 版本不兼容时会抛TypeError。IPv6Network(address, strictTrue)的输入形式与之基本平行但有两点差异字符串形式只接受前缀长度数字当前不支持展开的网络掩码2001:db00::0/24合法而2001:db00::0/ffff:ff00::不合法缺省前缀视为/128二元组中的掩码仅支持整数前缀长度。网络核心属性属性说明network_address网络地址与前缀长度共同唯一确定一个网络broadcast_address广播地址发往该地址的数据包应被网络上每个主机接收netmask/hostmask网络掩码 / 主机掩码均为地址对象prefixlen前缀长度比特数num_addresses网络内地址总数with_prefixlen/compressed/exploded掩码用前缀记法的字符串表示with_prefixlen与compressed恒等于str(network)exploded用全展开形式with_netmask网络掩码记法的字符串表示with_hostmask主机掩码记法的字符串表示底层实现值得留意broadcast_address与hostmask都用functools.cached_property惰性计算并缓存Lib/ipaddress.py前者是network_address | hostmask后者是netmask ^ 全1num_addresses则是广播地址与网络地址之差加一Lib/ipaddress.py。由于网络较大时如 IPv6/64遍历会不可行这些属性是 O(1) 计算绝不遍历。网络方法hosts()返回“可用主机”迭代器——IPv4 下排除网络地址与广播地址本身/31网络把网络地址与广播地址也纳入可用/32只返回该单主机Lib/ipaddress.py。 list(ip_network(192.0.2.0/29).hosts()) [IPv4Address(192.0.2.1), ..., IPv4Address(192.0.2.6)] list(ip_network(192.0.2.0/31).hosts()) [IPv4Address(192.0.2.0), IPv4Address(192.0.2.1)] list(ip_network(192.0.2.1/32).hosts()) [IPv4Address(192.0.2.1)]IPv6 的hosts()语义略有不同Lib/ipaddress.py排除的是Subnet-Router anycast 地址网络地址本身/127网络把该 anycast 地址也纳入/128返回单个主机。overlaps(other)两者任一全部/部分包含对方即返回True。其实现是把“对方网络地址或广播地址落在己方”与“己方地址落在对方”四种情形各判一次Lib/ipaddress.py。address_exclude(network)从本网络中剔除给定子网返回剩余部分的网络对象迭代器若给定网络未完全包含在本网络内则抛ValueError。其实现基于二分递归用能覆盖差集的最小网段表示“减法”结果 n1 ip_network(192.0.2.0/28) n2 ip_network(192.0.2.1/32) list(n1.address_exclude(n2)) [IPv4Network(192.0.2.8/29), IPv4Network(192.0.2.4/30), IPv4Network(192.0.2.2/31), IPv4Network(192.0.2.0/32)]subnets(prefixlen_diff1, new_prefixNone)把当前网络切分为若干子网。prefixlen_diff表示前缀长度增加的位数new_prefix直接指定子网期望前缀必须比当前前缀长。二者必须且只能设置其一。返回迭代器 list(ip_network(192.0.2.0/24).subnets()) [IPv4Network(192.0.2.0/25), IPv4Network(192.0.2.128/25)] list(ip_network(192.0.2.0/24).subnets(prefixlen_diff2)) [IPv4Network(192.0.2.0/26), IPv4Network(192.0.2.64/26), IPv4Network(192.0.2.128/26), IPv4Network(192.0.2.192/26)] list(ip_network(192.0.2.0/24).subnets(new_prefix26)) [IPv4Network(192.0.2.0/26), IPv4Network(192.0.2.64/26), IPv4Network(192.0.2.128/26), IPv4Network(192.0.2.192/26)] ip_network(192.0.2.0/24).subnets(new_prefix23) Traceback (most recent call last): ... ValueError: new prefix must be longersupernet(prefixlen_diff1, new_prefixNone)求包含当前网络的最小上层网络。prefixlen_diff为前缀减少位数new_prefix直接指定期望前缀必须比当前前缀短。同样二选一。返回单个网络对象 ip_network(192.0.2.0/24).supernet() IPv4Network(192.0.2.0/23) ip_network(192.0.2.0/24).supernet(prefixlen_diff2) IPv4Network(192.0.0.0/22) ip_network(192.0.2.0/24).supernet(new_prefix20) IPv4Network(192.0.0.0/20)subnet_of(other)/supernet_of(other)均自 3.7 起判断本网络是否是另一网络的子网 / 超网 a ip_network(192.168.1.0/24) b ip_network(192.168.1.128/30) b.subnet_of(a) True a.supernet_of(b) Truecompare_networks(other)仅比较网络地址不看主机位返回-1/0/1。3.7 起标记为 deprecated——它使用与、、完全一致的排序与比较算法直接用这些运算符即可 ip_network(192.0.2.1/32).compare_networks(ip_network(192.0.2.2/32)) -1 ip_network(192.0.2.1/32).compare_networks(ip_network(192.0.2.0/32)) 1 ip_network(192.0.2.1/32).compare_networks(ip_network(192.0.2.1/32)) 0next_network(next_prefixNone)自 3.16 起新增见 Lib/ipaddress.py求与当前网络“紧邻的下一个”指定前缀大小网络。next_prefix缺省时沿用当前前缀它必须在1与max_prefixlen之间否则抛ValueError若地址空间耗尽则同样抛ValueError。这非常适合做地址池的顺序分配 IPv4Network(192.0.2.0/24).next_network() IPv4Network(192.0.3.0/24) IPv4Network(192.0.2.0/24).next_network(next_prefix25) IPv4Network(192.0.3.0/25) IPv4Network(192.0.2.0/24).next_network(next_prefix23) IPv4Network(192.0.4.0/23) IPv4Network(192.0.80.0/22).next_network(next_prefix18) IPv4Network(192.0.128.0/18) IPv4Network(255.255.255.0/24).next_network() Traceback (most recent call last): ... ValueError: out of address space, cannot make another /24 networksubnet_of/supernet_of等在 Lib/test/test_ipaddress.py 等测试方法中有系统覆盖测试还专门验证了跨版本混用v4 与 v6时subnet_of等应安全返回False或抛TypeError见 Lib/test/test_ipaddress.py。网络运算符、迭代与容器行为网络对象支持逻辑比较运算符排序规则是先按网络地址、再按网络掩码。的实现要求版本、网络地址与掩码三者都一致Lib/ipaddress.py。迭代网络对象会得到网络内全部地址含网络地址与广播地址这些不可用地址只想要可用主机请用hosts()。其实现是range(network, broadcast1)的整数步进生成Lib/ipaddress.py for addr in IPv4Network(192.0.2.0/28): ... addr ... IPv4Address(192.0.2.0) ... IPv4Address(192.0.2.15)网络还是地址的容器支持下标索引与in成员测试__getitem__与__contains__实现见 Lib/ipaddress.py。成员测试的判定规则是目标地址与网络掩码按位与的结果等于网络地址版本不同时永远为False。 IPv4Network(192.0.2.0/28)[0] IPv4Address(192.0.2.0) IPv4Network(192.0.2.0/28)[15] IPv4Address(192.0.2.15) IPv4Address(192.0.2.6) in IPv4Network(192.0.2.0/28) True IPv4Address(192.0.3.6) in IPv4Network(192.0.2.0/28) False接口对象地址 网络信息的组合IPv4Interface(address)与IPv6Interface(address)描述“挂在某网络上的一张接口”。其address参数的语义与对应网络构造器相同但任意主机地址总是被接受不会因带主机位而报错。IPv4Interface是IPv4Address的子类因此继承地址类全部属性额外提供如下属性IPv6 对应类 Lib/ipaddress.py 语义相同ip剥离网络信息后的纯地址对象 interface IPv4Interface(192.0.2.5/24) interface.ip IPv4Address(192.0.2.5)network该接口所属网络 interface.network IPv4Network(192.0.2.0/24)with_prefixlen/with_netmask/with_hostmask三种掩码记法的接口字符串 interface.with_prefixlen 192.0.2.5/24 interface.with_netmask 192.0.2.5/255.255.255.0 interface.with_hostmask 192.0.2.5/0.0.0.255接口的比较语义比地址、网络更精细详见 Doc/library/ipaddress.rst判等/!IP 地址与网络都必须相同才相等接口对象与任何地址对象或网络对象都永不相等的排序/等同版本的接口与地址对象可以比较地址对象总是排在接口对象之前两个接口对象先按各自网络比较网络相同时再按 IP 地址比较。 IPv4Interface(192.0.2.5/24) IPv4Address(192.0.2.5) False IPv4Interface(192.0.2.5/24) IPv4Interface(192.0.2.5/24) True其它模块级函数函数功能v4_int_to_packed(address)把 IPv4 整数地址转为 4 字节大端bytes负数或超 32 位抛ValueErrorv6_int_to_packed(address)把 IPv6 整数地址转为 16 字节大端bytes越界抛ValueErrorsummarize_address_range(first, last)把[first, last]闭区间内的连续地址聚合成尽量少且对齐的网段返回迭代器collapse_addresses(addresses)将一批网络对象合并为尽可能少的相邻网段返回迭代器输入混入不同版本抛TypeErrorget_mixed_type_key(obj)为地址与网络混排的排序提供 key 函数用法示例 ipaddress.ip_address(3221225985) IPv4Address(192.0.2.1) ipaddress.v4_int_to_packed(3221225985) b\xc0\x00\x02\x01 [ipaddr for ipaddr in ipaddress.summarize_address_range( ... ipaddress.IPv4Address(192.0.2.0), ... ipaddress.IPv4Address(192.0.2.130))] [IPv4Network(192.0.2.0/25), IPv4Network(192.0.2.128/31), IPv4Network(192.0.2.130/32)] [ipaddr for ipaddr in ... ipaddress.collapse_addresses([ipaddress.IPv4Network(192.0.2.0/25), ... ipaddress.IPv4Network(192.0.2.128/25)])] [IPv4Network(192.0.2.0/24)]summarize_address_range在first/last非地址对象或版本不同时抛TypeErrorlast不大于first或版本号非法时抛ValueError。这类“区间聚合/反聚合”功能在配置防火墙白名单、生成 ACL 汇总条目时非常实用。get_mixed_type_key的典型用法是配合sorted()。由于地址与网络“本质不同”IPv4Address(192.0.2.0) IPv4Network(192.0.2.0/24)这种比较默认没有意义、会抛异常但你仍然可以借助该函数强制排序 sorted([IPv4Network(192.0.2.0/24), IPv4Address(192.0.2.5)], ... keyipaddress.get_mixed_type_key) [IPv4Address(192.0.2.5), IPv4Network(192.0.2.0/24)]行为示意地址按数值排序在前网络随后。规则细节以官方文档及 doctest 为准。自定义异常与更精确的错误定位模块为支持类构造器更具体的错误报告定义了继承自ValueError的两个异常AddressValueError与地址取值相关的错误NetmaskValueError与网络掩码相关的错误。工厂函数由于需同时尝试 IPv4 与 IPv6其合并后的ValueError信息往往较为笼统例如... does not appear to be an IPv4 or IPv6 address见 Lib/ipaddress.py而直接调用版本化构造器可以精确得到“地址段坏”还是“掩码段坏”。例如IPv4Address(192.168.1.256)抛AddressValueErrorIPv4Network(192.168.1.0/33)抛NetmaskValueError。写代码时可据此分别捕获并给出不同的用户提示。二者定义在 Lib/ipaddress.py构造器地址/掩码错误消息的专测集中在 Lib/test/test_ipaddress.py 的FactoryFunctionErrors及网络测试类中。版本演进要点速查把散落在文档中的versionadded/versionchanged汇总便于升级适配3.3模块加入标准库ip_address/ip_network/ip_interface工厂函数、地址/网络/接口对象齐备。3.4is_global属性加入。3.5reverse_pointer加入网络构造器新增“二元组 (地址, 掩码)”形式。3.7subnet_of/supernet_of加入compare_networks标记为 deprecated。3.8容忍 IPv4 字符串前导零含形似八进制的写法。3.9__format__格式化协议加入v4_int_to_packed等示例行为定型。3.9.5IPv4 字符串不再容忍前导零解析严格程度对齐 glibcinet_pton。3.13修正is_private/is_global的一批误判见前文列表IPv4Address.ipv6_mapped加入。3.14version与max_prefixlen同时以类属性形式暴露。3.16next_network()加入。测试与进一步研读仓库为ipaddress准备了约 2900 行的单元测试 Lib/test/test_ipaddress.py。测试按“v4/v6 公共测试混入 版本化测试类”组织CommonTestMixin_v4/CommonTestMixin_v6Lib/test/test_ipaddress.py承载两版本共享的断言逻辑AddressTestCase_v4/v6L196/L316、InterfaceTestCase_v4/v6L669/L832、NetworkTestCase_v4/v6L673/L836分别针对地址/接口/网络三类对象另有ComparisonTestsL902与IpaddrUnitTestL1083负责跨类比较与历史回归。安装并构建好本仓库的解释器后可运行./python -m test test_ipaddress若只运行部分用例可加-m指定测试方法名例如./python -m test test_ipaddress -m test_next_network阅读源码时建议沿“文档 → 实现 → 测试”的闭环先在 Doc/library/ipaddress.rst 查阅某 API 的官方语义再在 Lib/ipaddress.py 中看具体算法前缀解析_split_optional_netmask、_make_netmask、子网切分、summarize_address_range的区间对齐逻辑等最后到 Lib/test/test_ipaddress.py 找对应断言来确认边界行为。这样既能获得权威定义又能理解每个方法为何这样实现从而在防火墙规则校验、网络扫描、DHCP/地址池管理、配置模板校验等业务中可靠地使用这套 API。【免费下载链接】cpythonThe Python programming language项目地址: https://gitcode.com/GitHub_Trending/cp/cpython创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考