ipaddress --- IPv4/IPv6 操作库

源代码: Lib/ipaddress.py


ipaddress 模块提供了创建、操作 IPv4 和 IPv6 地址与网络的功能。

此模块中的函数和类使得处理与 IP 地址相关的各种任务变得简单明了,包括检查两个主机是否在同一子网、迭代特定子网中的所有主机、检查字符串是否表示有效的 IP 地址或网络定义等等。

这是完整的模块 API 参考 --- 有关概述和介绍,请参阅 ipaddress 模块介绍

在 3.3 版本加入。

便捷工厂函数

ipaddress 模块提供了工厂函数,可以方便地创建 IP 地址、网络和接口。

ipaddress.ip_address(address)

根据传入的 IP 地址参数返回一个 IPv4AddressIPv6Address 对象。可以提供 IPv4 或 IPv6 地址;小于 2**32 的整数默认被视为 IPv4 地址。如果 address 不表示有效的 IPv4 或 IPv6 地址,则会引发 ValueError

>>> ipaddress.ip_address('192.168.0.1')
IPv4Address('192.168.0.1')
>>> ipaddress.ip_address('2001:db8::')
IPv6Address('2001:db8::')
ipaddress.ip_network(address, strict=True)

根据传入的 IP 地址参数返回一个 IPv4NetworkIPv6Network 对象。address 是一个表示 IP 网络的字符串或整数。可以提供 IPv4 或 IPv6 网络;小于 2**32 的整数默认被视为 IPv4 地址。strict 会被传递给 IPv4NetworkIPv6Network 的构造函数。如果 address 不表示有效的 IPv4 或 IPv6 地址,或者网络地址中设置了主机位,则会引发 ValueError

>>> ipaddress.ip_network('192.168.0.0/28')
IPv4Network('192.168.0.0/28')
ipaddress.ip_interface(address)

根据传入的 IP 地址参数返回一个 IPv4InterfaceIPv6Interface 对象。address 是一个表示 IP 地址的字符串或整数。可以提供 IPv4 或 IPv6 地址;小于 2**32 的整数默认被视为 IPv4 地址。如果 address 不表示有效的 IPv4 或 IPv6 地址,则会引发 ValueError

这些便捷函数的一个缺点是,由于需要同时处理 IPv4 和 IPv6 格式,错误消息提供的精确错误信息非常有限,因为函数不知道预期的是 IPv4 还是 IPv6 格式。通过直接调用相应版本特定的类构造函数,可以获得更详细的错误报告。

IP 地址

地址对象

IPv4AddressIPv6Address 对象共享许多共同的属性。一些仅对 IPv6 地址有意义的属性也由 IPv4Address 对象实现,以便于编写能正确处理两种 IP 版本的代码。地址对象是可哈希的,因此可以用作字典的键。

class ipaddress.IPv4Address(address)

构造一个 IPv4 地址。如果 address 不是一个有效的 IPv4 地址,则会引发 AddressValueError

以下构成一个有效的 IPv4 地址:

  1. 一个点分十进制表示的字符串,由四个十进制整数组成,范围在 0-255(含)之间,用点分隔(例如 192.168.0.1)。每个整数代表地址中的一个八位字节(byte)。不允许前导零,以防止与八进制表示法混淆。

  2. 一个能容纳在 32 位中的整数。

  3. 一个打包成长度为 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 inet_pton() 一样进行严格解析。

version

相应的版本号:IPv4 为 4,IPv6 为 6

在 3.14 版本发生变更: 使其在类上可用。

max_prefixlen

此版本地址表示中的总位数:IPv4 为 32,IPv6 为 128

前缀定义了地址中用于比较以确定地址是否属于某个网络的前导位数。

在 3.14 版本发生变更: 使其在类上可用。

compressed
exploded

点分十进制表示的字符串。表示中从不包含前导零。

由于 IPv4 没有为八位字节为零的地址定义简写表示法,这两个属性对于 IPv4 地址总是与 str(addr) 相同。提供这些属性使得编写能够同时处理 IPv4 和 IPv6 地址的显示代码更加容易。

packed

此地址的二进制表示 --- 一个适当长度的 bytes 对象(最高有效八位字节在前)。IPv4 为 4 字节,IPv6 为 16 字节。

reverse_pointer

IP 地址的反向 DNS PTR 记录的名称,例如:

>>> 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.arpa'

这是可用于执行 PTR 查找的名称,而不是解析后的主机名本身。

在 3.5 版本加入。

is_multicast

如果地址被保留用于多播,则为 True。参见 RFC 3171(适用于 IPv4)或 RFC 2373(适用于 IPv6)。

is_private

如果地址被 iana-ipv4-special-registry(适用于 IPv4)或 iana-ipv6-special-registry(适用于 IPv6)定义为非全局可达,则为 True,但有以下例外:

  • 对于共享地址空间(100.64.0.0/10),is_privateFalse

  • 对于 IPv4 映射的 IPv6 地址,is_private 的值由底层 IPv4 地址的语义决定,并满足以下条件(参见 IPv6Address.ipv4_mapped):

    address.is_private == address.ipv4_mapped.is_private
    

is_private 的值与 is_global 相反,但共享地址空间(100.64.0.0/10 范围)除外,此时它们都为 False

在 3.13 版本发生变更: 修复了一些假阳性和假阴性。

  • 192.0.0.0/24 被视为私有,但 192.0.0.9/32192.0.0.10/32 除外(以前:只有 192.0.0.0/29 子范围被视为私有)。

  • 64:ff9b:1::/48 被视为私有。

  • 2002::/16 被视为私有。

  • 2001::/23(否则被视为私有)内存在例外:2001:1::1/1282001:1::2/1282001:3::/322001:4:112::/482001:20::/282001:30::/28。这些例外不被视为私有。

is_global

如果地址被 iana-ipv4-special-registry(适用于 IPv4)或 iana-ipv6-special-registry(适用于 IPv6)定义为全局可达,则为 True,但有以下例外:

对于 IPv4 映射的 IPv6 地址,is_private 的值由底层 IPv4 地址的语义决定,并满足以下条件(参见 IPv6Address.ipv4_mapped):

address.is_global == address.ipv4_mapped.is_global

is_global 的值与 is_private 相反,但共享地址空间(100.64.0.0/10 范围)除外,此时它们都为 False

在 3.4 版本加入。

在 3.13 版本发生变更: 修复了一些假阳性和假阴性,详见 is_private

is_unspecified

如果地址是未指定的,则为 True。参见 RFC 5735(适用于 IPv4)或 RFC 2373(适用于 IPv6)。

is_reserved

如果地址被 IETF 标记为保留,则为 True。对于 IPv4,这仅指 240.0.0.0/4,即 Reserved 地址块。对于 IPv6,这是指所有被分配为 Reserved by IETF 以供将来使用的地址。

备注

对于 IPv4,is_reservediana-ipv4-special-registryReserved-by-Protocol 列的地址块值无关。

注意

对于 IPv6,fec0::/10,一个以前的站点本地范围地址前缀,目前被排除在该列表之外(参见 is_site_localRFC 3879)。

is_loopback

如果这是一个环回地址,则为 True。参见 RFC 3330(适用于 IPv4)或 RFC 2373(适用于 IPv6)。

如果地址被保留用于链路本地使用,则为 True。参见 RFC 3927

ipv6_mapped

一个表示 IPv4 映射的 IPv6 地址的 IPv4Address 对象。参见 RFC 4291

在 3.13 版本加入。

IPv4Address.__format__(fmt)

返回由显式格式字符串控制的 IP 地址字符串表示。fmt 可以是以下之一:'s'(默认选项),等同于 str()'b' 表示零填充的二进制字符串;'X''x' 表示大写或小写的十六进制表示;或 'n',对于 IPv4 地址等同于 'b',对于 IPv6 等同于 'x'。对于二进制和十六进制表示,可以使用形式说明符 '#' 和分组选项 '_'__format__formatstr.format 和 f-string 使用。

>>> 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_1000'

在 3.9 版本中新增。

class ipaddress.IPv6Address(address)

构造一个 IPv6 地址。如果 address 不是一个有效的 IPv6 地址,则会引发 AddressValueError

以下构成一个有效的 IPv6 地址:

  1. 一个由八组四位十六进制数字组成的字符串,每组代表 16 位。这些组由冒号分隔。这描述了一种*展开*(完整)表示法。该字符串也可以通过多种方式进行*压缩*(简写表示法)。详见 RFC 4291。例如,"0000:0000:0000:0000:0000:0abc:0007:0def" 可以压缩为 "::abc:7:def"

    可选地,字符串还可以带有一个范围区域 ID(scope zone ID),用后缀 %scope_id 表示。如果存在,范围 ID 必须非空,且不能包含 %。详见 RFC 4007。例如,fe80::1234%1 可能标识节点上第一个链路的地址 fe80::1234

  2. 一个能容纳在 128 位中的整数。

  3. 一个打包成长度为 16 的 bytes 对象的整数,大端序。

>>> ipaddress.IPv6Address('2001:db8::1000')
IPv6Address('2001:db8::1000')
>>> ipaddress.IPv6Address('ff02::5678%1')
IPv6Address('ff02::5678%1')
compressed

地址的简短形式表示,省略了组中的前导零,并将最长的一组完全由零组成的序列压缩成一个单独的空组。

对于 IPv6 地址,这也是 str(addr) 返回的值。

exploded

地址的完整形式表示,包含所有前导零和完全由零组成的组。

对于以下属性和方法,请参阅 IPv4Address 类的相应文档:

packed
reverse_pointer
version
max_prefixlen
is_multicast
is_private
is_global

在 3.4 版本加入。

is_unspecified
is_reserved
is_loopback
is_site_local

如果地址被保留用于站点本地使用,则为 True。请注意,站点本地地址空间已被 RFC 3879 废弃。使用 is_private 来测试此地址是否在 RFC 4193 定义的唯一本地地址空间内。

ipv4_mapped

对于看起来是 IPv4 映射地址(以 ::FFFF/96 开头)的地址,此属性将报告嵌入的 IPv4 地址。对于任何其他地址,此属性将为 None

scope_id

对于由 RFC 4007 定义的范围地址,此属性以字符串形式标识地址所属范围的特定区域。如果未指定范围区域,此属性将为 None

sixtofour

对于看起来是 6to4 地址(以 2002::/16 开头)的地址,如 RFC 3056 所定义,此属性将报告嵌入的 IPv4 地址。对于任何其他地址,此属性将为 None

teredo

对于看起来是 Teredo 地址(以 2001::/32 开头)的地址,如 RFC 4380 所定义,此属性将报告嵌入的 (server, client) IP 地址对。对于任何其他地址,此属性将为 None

IPv6Address.__format__(fmt)

请参阅 IPv4Address 中相应方法的文档。

在 3.9 版本中新增。

转换为字符串和整数

为了与网络接口(如 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 范围地址在转换为整数时会不带范围区域 ID。

运算符

地址对象支持一些运算符。除非另有说明,运算符只能在兼容的对象之间应用(即 IPv4 与 IPv4,IPv6 与 IPv6)。

比较运算符

地址对象可以使用通常的比较运算符进行比较。具有不同范围区域 ID 的相同 IPv6 地址不相等。一些示例:

>>> IPv4Address('127.0.0.2') > IPv4Address('127.0.0.1')
True
>>> IPv4Address('127.0.0.2') == IPv4Address('127.0.0.1')
False
>>> IPv4Address('127.0.0.2') != IPv4Address('127.0.0.1')
True
>>> IPv6Address('fe80::1234') == IPv6Address('fe80::1234%1')
False
>>> IPv6Address('fe80::1234%1') != IPv6Address('fe80::1234%2')
True

算术运算符

可以对地址对象进行整数的加减运算。一些示例:

>>> 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):
  File "<stdin>", line 1, in <module>
ipaddress.AddressValueError: 4294967296 (>= 2**32) is not permitted as an IPv4 address

IP 网络定义

IPv4NetworkIPv6Network 对象提供了一种定义和检查 IP 网络定义的机制。网络定义由一个*掩码*和一个*网络地址*组成,因此定义了一个 IP 地址范围,这些 IP 地址在与掩码进行掩码运算(二进制与)后等于网络地址。例如,一个掩码为 255.255.255.0、网络地址为 192.168.1.0 的网络定义,包含了从 192.168.1.0192.168.1.255 的 IP 地址范围(包含两端)。

前缀、网络掩码和主机掩码

有几种等效的方式来指定 IP 网络掩码。*前缀* /<nbits> 是一种表示法,表示网络掩码中有多少个高位被设置为 1。*网络掩码*是一个 IP 地址,其中有若干高位被设置为 1。因此,前缀 /24 等同于 IPv4 中的网络掩码 255.255.255.0,或 IPv6 中的 ffff:ff00::。此外,*主机掩码*是*网络掩码*的逻辑反码,有时用于表示网络掩码(例如在思科访问控制列表中)。与 IPv4 中的 /24 等效的主机掩码是 0.0.0.255

网络对象

地址对象实现的所有属性,网络对象也都实现。此外,网络对象还实现了额外的属性。所有这些属性在 IPv4NetworkIPv6Network 之间是通用的,为避免重复,仅在 IPv4Network 中进行文档说明。网络对象是可哈希的,因此可以用作字典的键。

class ipaddress.IPv4Network(address, strict=True)

构造一个 IPv4 网络定义。address 可以是以下之一:

  1. 一个由 IP 地址和可选掩码组成的字符串,用斜杠(/)分隔。IP 地址是网络地址,掩码可以是一个数字,表示它是一个*前缀*,也可以是一个 IPv4 地址的字符串表示。如果是后者,如果掩码以非零字段开头,则被解释为*网络掩码*;如果以零字段开头,则被解释为*主机掩码*,唯一的例外是全零掩码,它被视为*网络掩码*。如果未提供掩码,则默认为 /32

    例如,以下 address 规范是等效的:192.168.1.0/24192.168.1.0/255.255.255.0192.168.1.0/0.0.0.255

  2. 一个能容纳在 32 位中的整数。这相当于一个单地址网络,其中网络地址为 address,掩码为 /32

  3. 一个打包成长度为 4 的 bytes 对象的整数,大端序。其解释与整数 address 类似。

  4. 一个由地址描述和网络掩码组成的二元组,其中地址描述可以是字符串、32 位整数、4 字节打包整数或现有的 IPv4Address 对象;网络掩码可以是一个表示前缀长度的整数(例如 24)或一个表示前缀掩码的字符串(例如 255.255.255.0)。

如果 address 不是有效的 IPv4 地址,则会引发 AddressValueError。如果掩码对 IPv4 地址无效,则会引发 NetmaskValueError

如果 strictTrue 且提供的地址中设置了主机位,则会引发 ValueError。否则,主机位将被屏蔽掉以确定适当的网络地址。

除非另有说明,所有接受其他网络/地址对象的网络方法,如果参数的 IP 版本与 self 不兼容,将引发 TypeError

在 3.5 版本发生变更: address 构造函数参数添加了二元组形式。

version
max_prefixlen

请参阅 IPv4Address 中相应属性的文档。

is_multicast
is_private
is_unspecified
is_reserved
is_loopback

如果这些属性对于网络地址和广播地址都为真,那么它们对于整个网络也为真。

network_address

网络的网络地址。网络地址和前缀长度共同唯一地定义了一个网络。

broadcast_address

网络的广播地址。发送到广播地址的数据包应该被网络上的每个主机接收。

hostmask

主机掩码,作为一个 IPv4Address 对象。

netmask

网络掩码,作为一个 IPv4Address 对象。

with_prefixlen
compressed
exploded

网络的字符串表示,掩码采用前缀表示法。

with_prefixlencompressed 总是与 str(network) 相同。exploded 使用网络地址的展开形式。

with_netmask

网络的字符串表示,掩码采用网络掩码表示法。

with_hostmask

网络的字符串表示,掩码采用主机掩码表示法。

num_addresses

网络中的地址总数。

prefixlen

网络前缀的长度,以位为单位。

hosts()

返回网络中可用主机的迭代器。可用主机是属于该网络的所有 IP 地址,除了网络地址本身和网络广播地址。对于掩码长度为 31 的网络,网络地址和网络广播地址也包含在结果中。掩码为 32 的网络将返回一个包含单个主机地址的列表。

>>> list(ip_network('192.0.2.0/29').hosts())
[IPv4Address('192.0.2.1'), IPv4Address('192.0.2.2'),
 IPv4Address('192.0.2.3'), IPv4Address('192.0.2.4'),
 IPv4Address('192.0.2.5'), 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')]
overlaps(other)

如果此网络部分或全部包含在 other 中,或者 other 全部包含在此网络中,则为 True

address_exclude(network)

计算从此网络中移除给定 network 后产生的网络定义。返回一个网络对象的迭代器。如果 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_diff=1, new_prefix=None)

根据参数值,返回构成当前网络定义的子网。prefixlen_diff 是我们的前缀长度应增加的数量。new_prefix 是子网所需的新前缀;它必须大于我们的前缀。prefixlen_diffnew_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_diff=2))
[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_prefix=26))
[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_prefix=23))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    raise ValueError('new prefix must be longer')
ValueError: new prefix must be longer
>>> list(ip_network('192.0.2.0/24').subnets(new_prefix=25))
[IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/25')]
supernet(prefixlen_diff=1, new_prefix=None)

根据参数值,返回包含此网络定义的超网。prefixlen_diff 是我们的前缀长度应减少的数量。new_prefix 是超网所需的新前缀;它必须小于我们的前缀。prefixlen_diffnew_prefix 中必须且只能设置一个。返回一个单一的网络对象。

>>> ip_network('192.0.2.0/24').supernet()
IPv4Network('192.0.2.0/23')
>>> ip_network('192.0.2.0/24').supernet(prefixlen_diff=2)
IPv4Network('192.0.0.0/22')
>>> ip_network('192.0.2.0/24').supernet(new_prefix=20)
IPv4Network('192.0.0.0/20')
subnet_of(other)

如果此网络是 other 的子网,则返回 True

>>> a = ip_network('192.168.1.0/24')
>>> b = ip_network('192.168.1.128/30')
>>> b.subnet_of(a)
True

在 3.7 版本加入。

supernet_of(other)

如果此网络是 other 的超网,则返回 True

>>> a = ip_network('192.168.1.0/24')
>>> b = ip_network('192.168.1.128/30')
>>> a.supernet_of(b)
True

在 3.7 版本加入。

compare_networks(other)

将此网络与 other 进行比较。在此比较中,只考虑网络地址;不考虑主机位。返回 -101

>>> 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'))
0

自 3.7 版本起已弃用: 它使用与“<”、“==”和“>”相同的排序和比较算法。

class ipaddress.IPv6Network(address, strict=True)

构造一个 IPv6 网络定义。address 可以是以下之一:

  1. 一个由 IP 地址和可选前缀长度组成的字符串,用斜杠(/)分隔。IP 地址是网络地址,前缀长度必须是一个数字,即*前缀*。如果未提供前缀长度,则默认为 /128

    请注意,目前不支持展开的网络掩码。这意味着 2001:db00::0/24 是一个有效的参数,而 2001:db00::0/ffff:ff00:: 不是。

  2. 一个能容纳在 128 位中的整数。这相当于一个单地址网络,其中网络地址为 address,掩码为 /128

  3. 一个打包成长度为 16 的 bytes 对象的整数,大端序。其解释与整数 address 类似。

  4. 一个由地址描述和网络掩码组成的二元组,其中地址描述可以是字符串、128 位整数、16 字节打包整数或现有的 IPv6Address 对象;网络掩码是一个表示前缀长度的整数。

如果 address 不是有效的 IPv6 地址,则会引发 AddressValueError。如果掩码对 IPv6 地址无效,则会引发 NetmaskValueError

如果 strictTrue 且提供的地址中设置了主机位,则会引发 ValueError。否则,主机位将被屏蔽掉以确定适当的网络地址。

在 3.5 版本发生变更: address 构造函数参数添加了二元组形式。

version
max_prefixlen
is_multicast
is_private
is_unspecified
is_reserved
is_loopback
network_address
broadcast_address
hostmask
netmask
with_prefixlen
compressed
exploded
with_netmask
with_hostmask
num_addresses
prefixlen
hosts()

返回网络中可用主机的迭代器。可用主机是属于该网络的所有 IP 地址,除了子网-路由器任播地址。对于掩码长度为 127 的网络,子网-路由器任播地址也包含在结果中。掩码为 128 的网络将返回一个包含单个主机地址的列表。

overlaps(other)
address_exclude(network)
subnets(prefixlen_diff=1, new_prefix=None)
supernet(prefixlen_diff=1, new_prefix=None)
subnet_of(other)
supernet_of(other)
compare_networks(other)

请参阅 IPv4Network 中相应属性的文档。

is_site_local

如果该属性对于网络地址和广播地址都为真,则对于整个网络也为真。

运算符

网络对象支持一些运算符。除非另有说明,运算符只能在兼容的对象之间应用(即 IPv4 与 IPv4,IPv6 与 IPv6)。

逻辑运算符

网络对象可以使用通常的逻辑运算符进行比较。网络对象的排序首先按网络地址,然后按网络掩码。

迭代

可以迭代网络对象以列出属于该网络的所有地址。迭代时,将返回*所有*主机,包括不可用的主机(对于可用主机,请使用 hosts() 方法)。一个示例:

>>> for addr in IPv4Network('192.0.2.0/28'):
...     addr
...
IPv4Address('192.0.2.0')
IPv4Address('192.0.2.1')
IPv4Address('192.0.2.2')
IPv4Address('192.0.2.3')
IPv4Address('192.0.2.4')
IPv4Address('192.0.2.5')
IPv4Address('192.0.2.6')
IPv4Address('192.0.2.7')
IPv4Address('192.0.2.8')
IPv4Address('192.0.2.9')
IPv4Address('192.0.2.10')
IPv4Address('192.0.2.11')
IPv4Address('192.0.2.12')
IPv4Address('192.0.2.13')
IPv4Address('192.0.2.14')
IPv4Address('192.0.2.15')

网络作为地址的容器

网络对象可以作为地址的容器。一些示例:

>>> 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

接口对象

接口对象是可哈希的,因此可以用作字典的键。

class ipaddress.IPv4Interface(address)

构造一个 IPv4 接口。address 的含义与 IPv4Network 构造函数中相同,但始终接受任意主机地址。

IPv4InterfaceIPv4Address 的子类,因此它继承了该类的所有属性。此外,还提供以下属性:

ip

不带网络信息的地址(IPv4Address)。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.ip
IPv4Address('192.0.2.5')
network

此接口所属的网络(IPv4Network)。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.network
IPv4Network('192.0.2.0/24')
with_prefixlen

接口的字符串表示,掩码采用前缀表示法。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.with_prefixlen
'192.0.2.5/24'
with_netmask

接口的字符串表示,网络作为网络掩码。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.with_netmask
'192.0.2.5/255.255.255.0'
with_hostmask

接口的字符串表示,网络作为主机掩码。

>>> interface = IPv4Interface('192.0.2.5/24')
>>> interface.with_hostmask
'192.0.2.5/0.0.0.255'
class ipaddress.IPv6Interface(address)

构造一个 IPv6 接口。address 的含义与 IPv6Network 构造函数中相同,但始终接受任意主机地址。

IPv6InterfaceIPv6Address 的子类,因此它继承了该类的所有属性。此外,还提供以下属性:

ip
network
with_prefixlen
with_netmask
with_hostmask

请参阅 IPv4Interface 中相应属性的文档。

运算符

接口对象支持一些运算符。除非另有说明,运算符只能在兼容的对象之间应用(即 IPv4 与 IPv4,IPv6 与 IPv6)。

逻辑运算符

接口对象可以使用通常的逻辑运算符进行比较。

对于相等性比较(==!=),IP 地址和网络都必须相同,对象才相等。接口对象不会与任何地址或网络对象相等。

对于排序(<> 等),规则不同。具有相同 IP 版本的接口和地址对象可以进行比较,地址对象总是排在接口对象之前。两个接口对象首先按其网络进行比较,如果网络相同,则按其 IP 地址进行比较。

其他模块级函数

该模块还提供了以下模块级函数:

ipaddress.v4_int_to_packed(address)

将地址表示为网络顺序(大端序)的 4 个打包字节。address 是 IPv4 IP 地址的整数表示。如果整数为负数或太大而不能成为 IPv4 IP 地址,则会引发 ValueError

>>> ipaddress.ip_address(3221225985)
IPv4Address('192.0.2.1')
>>> ipaddress.v4_int_to_packed(3221225985)
b'\xc0\x00\x02\x01'
ipaddress.v6_int_to_packed(address)

将地址表示为网络顺序(大端序)的 16 个打包字节。address 是 IPv6 IP 地址的整数表示。如果整数为负数或太大而不能成为 IPv6 IP 地址,则会引发 ValueError

ipaddress.summarize_address_range(first, last)

给定第一个和最后一个 IP 地址,返回一个汇总网络范围的迭代器。first 是范围内的第一个 IPv4AddressIPv6Addresslast 是范围内的最后一个 IPv4AddressIPv6Address。如果 firstlast 不是 IP 地址或它们的版本不同,则会引发 TypeError。如果 last 不大于 first,或者 first 地址的版本不是 4 或 6,则会引发 ValueError

>>> [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')]
ipaddress.collapse_addresses(addresses)

返回一个折叠后的 IPv4NetworkIPv6Network 对象迭代器。addresses 是一个由 IPv4NetworkIPv6Network 对象组成的可迭代对象。如果 addresses 包含混合版本的对象,则会引发 TypeError

>>> [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')]
ipaddress.get_mixed_type_key(obj)

返回一个适合在网络和地址之间进行排序的键。地址和网络对象默认是不可排序的;它们在根本上是不同的,所以表达式

IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24')

没有意义。然而,在某些情况下,你可能希望 ipaddress 无论如何都要对它们进行排序。如果需要这样做,你可以将此函数用作 sorted()key 参数。

obj 是一个网络或地址对象。

自定义异常

为了支持从类构造函数中报告更具体的错误,该模块定义了以下异常

exception ipaddress.AddressValueError(ValueError)

任何与地址相关的值错误。

exception ipaddress.NetmaskValueError(ValueError)

任何与子网掩码相关的值错误。