“Python/docs/3.9/howto/ipaddress”的版本间差异

来自菜鸟教程
Python/docs/3.9/howto/ipaddress
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:ipaddress 模块简介 — Python 文档}}
 
<div id="an-introduction-to-the-ipaddress-module" class="section">
 
<div id="an-introduction-to-the-ipaddress-module" class="section">
  
 
<span id="ipaddress-howto"></span>
 
<span id="ipaddress-howto"></span>
= An introduction to the ipaddress module =
+
= ipaddress 模块介绍 =
  
; author
+
; 作者
: Peter Moody
+
: 彼得·穆迪
; author
+
; 作者
: Nick Coghlan
+
: 尼克·科格兰
  
 
<div class="topic">
 
<div class="topic">
  
Overview
+
概述
  
This document aims to provide a gentle introduction to the
+
本文档旨在简要介绍 [[../../library/ipaddress#module-ipaddress|ipaddress]] 模块。 它主要针对不熟悉 IP 网络术语的用户,但对于想要了解 [[../../library/ipaddress#module-ipaddress|ipaddress]] 如何表示 IP 网络寻址概念的网络工程师也可能有用。
[[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]] module. It is aimed primarily at users that aren't
 
already familiar with IP networking terminology, but may also be useful
 
to network engineers wanting an overview of how [[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]]
 
represents IP network addressing concepts.
 
  
  
第23行: 第20行:
 
<div id="creating-address-network-interface-objects" class="section">
 
<div id="creating-address-network-interface-objects" class="section">
  
== Creating Address/Network/Interface objects ==
+
== 创建地址/网络/接口对象 ==
  
Since [[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]] is a module for inspecting and manipulating IP addresses,
+
由于 [[../../library/ipaddress#module-ipaddress|ipaddress]] 是一个用于检查和操作 IP 地址的模块,因此您要做的第一件事就是创建一些对象。 您可以使用 [[../../library/ipaddress#module-ipaddress|ipaddress]] 从字符串和整数创建对象。
the first thing you'll want to do is create some objects. You can use
 
[[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]] to create objects from strings and integers.
 
  
 
<div id="a-note-on-ip-versions" class="section">
 
<div id="a-note-on-ip-versions" class="section">
  
=== A Note on IP Versions ===
+
=== 关于 IP 版本的说明 ===
  
For readers that aren't particularly familiar with IP addressing, it's
+
对于不是特别熟悉 IP 寻址的读者,重要的是要知道 Internet 协议目前正在从协议的第 4 版迁移到第 6 版。 这种转变的发生主要是因为该协议的第 4 版没有提供足够的地址来满足全世界的需求,特别是考虑到直接连接到互联网的设备数量不断增加。
important to know that the Internet Protocol is currently in the process
 
of moving from version 4 of the protocol to version 6. This transition is
 
occurring largely because version 4 of the protocol doesn't provide enough
 
addresses to handle the needs of the whole world, especially given the
 
increasing number of devices with direct connections to the internet.
 
  
Explaining the details of the differences between the two versions of the
+
详细解释两个版本的协议差异超出了本介绍的范围,但读者至少需要意识到这两个版本的存在,并且有时需要强制使用一个版本或其他。
protocol is beyond the scope of this introduction, but readers need to at
 
least be aware that these two versions exist, and it will sometimes be
 
necessary to force the use of one version or the other.
 
  
  
第49行: 第36行:
 
<div id="ip-host-addresses" class="section">
 
<div id="ip-host-addresses" class="section">
  
=== IP Host Addresses ===
+
=== IP 主机地址 ===
  
Addresses, often referred to as &quot;host addresses&quot; are the most basic unit
+
地址,通常称为“主机地址”,是使用 IP 寻址时最基本的单位。 创建地址最简单的方法是使用 [[../../library/ipaddress#ipaddress|ipaddress.ip_address()]] 工厂函数,它会根据传入的值自动确定是创建 IPv4 还是 IPv6 地址:
when working with IP addressing. The simplest way to create addresses is
 
to use the [[../../library/ipaddress#ipaddress|<code>ipaddress.ip_address()</code>]] factory function, which automatically
 
determines whether to create an IPv4 or IPv6 address based on the passed in
 
value:
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第61行: 第44行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_address('192.0.2.1')
+
<syntaxhighlight lang="python">>>> ipaddress.ip_address('192.0.2.1')
 
IPv4Address('192.0.2.1')
 
IPv4Address('192.0.2.1')
&gt;&gt;&gt; ipaddress.ip_address('2001:DB8::1')
+
>>> ipaddress.ip_address('2001:DB8::1')
IPv6Address('2001:db8::1')</pre>
+
IPv6Address('2001:db8::1')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Addresses can also be created directly from integers. Values that will
+
地址也可以直接从整数创建。 将适合 32 位的值假定为 IPv4 地址:
fit within 32 bits are assumed to be IPv4 addresses:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第76行: 第58行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_address(3221225985)
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_address(3221225985)
 
IPv4Address('192.0.2.1')
 
IPv4Address('192.0.2.1')
&gt;&gt;&gt; ipaddress.ip_address(42540766411282592856903984951653826561)
+
>>> ipaddress.ip_address(42540766411282592856903984951653826561)
IPv6Address('2001:db8::1')</pre>
+
IPv6Address('2001:db8::1')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
To force the use of IPv4 or IPv6 addresses, the relevant classes can be
+
要强制使用 IPv4 IPv6 地址,可以直接调用相关类。 这对于强制为小整数创建 IPv6 地址特别有用:
invoked directly. This is particularly useful to force creation of IPv6
 
addresses for small integers:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第92行: 第72行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_address(1)
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_address(1)
 
IPv4Address('0.0.0.1')
 
IPv4Address('0.0.0.1')
&gt;&gt;&gt; ipaddress.IPv4Address(1)
+
>>> ipaddress.IPv4Address(1)
 
IPv4Address('0.0.0.1')
 
IPv4Address('0.0.0.1')
&gt;&gt;&gt; ipaddress.IPv6Address(1)
+
>>> ipaddress.IPv6Address(1)
IPv6Address('::1')</pre>
+
IPv6Address('::1')</syntaxhighlight>
  
 
</div>
 
</div>
第106行: 第86行:
 
<div id="defining-networks" class="section">
 
<div id="defining-networks" class="section">
  
=== Defining Networks ===
+
=== 定义网络 ===
  
Host addresses are usually grouped together into IP networks, so
+
主机地址通常组合到 IP 网络中,因此 [[../../library/ipaddress#module-ipaddress|ipaddress]] 提供了一种创建、检查和操作网络定义的方法。 IP 网络对象由定义作为该网络一部分的主机地址范围的字符串构成。 该信息的最简单形式是“网络地址/网络前缀”对,其中前缀定义了前导位的数量,用于确定地址是否是网络的一部分,网络地址定义了预期值那些位。
[[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]] provides a way to create, inspect and manipulate network
 
definitions. IP network objects are constructed from strings that define the
 
range of host addresses that are part of that network. The simplest form
 
for that information is a &quot;network address/network prefix&quot; pair, where the
 
prefix defines the number of leading bits that are compared to determine
 
whether or not an address is part of the network and the network address
 
defines the expected value of those bits.
 
  
As for addresses, a factory function is provided that determines the correct
+
至于地址,提供了一个工厂函数,可以自动确定正确的 IP 版本:
IP version automatically:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第124行: 第96行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_network('192.0.2.0/24')
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_network('192.0.2.0/24')
 
IPv4Network('192.0.2.0/24')
 
IPv4Network('192.0.2.0/24')
&gt;&gt;&gt; ipaddress.ip_network('2001:db8::0/96')
+
>>> ipaddress.ip_network('2001:db8::0/96')
IPv6Network('2001:db8::/96')</pre>
+
IPv6Network('2001:db8::/96')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Network objects cannot have any host bits set. The practical effect of this
+
网络对象不能设置任何主机位。 这样做的实际效果是 <code>192.0.2.1/24</code> 没有描述网络。 此类定义被称为接口对象,因为 ip-on-a-network 表示法通常用于描述给定网络上计算机的网络接口,并在下一节中进一步描述。
is that <code>192.0.2.1/24</code> does not describe a network. Such definitions are
 
referred to as interface objects since the ip-on-a-network notation is
 
commonly used to describe network interfaces of a computer on a given network
 
and are described further in the next section.
 
  
By default, attempting to create a network object with host bits set will
+
默认情况下,尝试创建设置了主机位的网络对象将导致引发 [[../../library/exceptions#ValueError|ValueError]]。 要请求将附加位强制为零,可以将标志 <code>strict=False</code> 传递给构造函数:
result in [[../../library/exceptions#ValueError|<code>ValueError</code>]] being raised. To request that the
 
additional bits instead be coerced to zero, the flag <code>strict=False</code> can
 
be passed to the constructor:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第147行: 第112行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_network('192.0.2.1/24')
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_network('192.0.2.1/24')
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
   ...
 
   ...
 
ValueError: 192.0.2.1/24 has host bits set
 
ValueError: 192.0.2.1/24 has host bits set
&gt;&gt;&gt; ipaddress.ip_network('192.0.2.1/24', strict=False)
+
>>> ipaddress.ip_network('192.0.2.1/24', strict=False)
IPv4Network('192.0.2.0/24')</pre>
+
IPv4Network('192.0.2.0/24')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
While the string form offers significantly more flexibility, networks can
+
虽然字符串形式提供了更大的灵活性,但网络也可以用整数定义,就像主机地址一样。 在这种情况下,网络被认为只包含由整数标识的单个地址,因此网络前缀包括整个网络地址:
also be defined with integers, just like host addresses. In this case, the
 
network is considered to contain only the single address identified by the
 
integer, so the network prefix includes the entire network address:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第166行: 第128行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_network(3221225984)
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_network(3221225984)
 
IPv4Network('192.0.2.0/32')
 
IPv4Network('192.0.2.0/32')
&gt;&gt;&gt; ipaddress.ip_network(42540766411282592856903984951653826560)
+
>>> ipaddress.ip_network(42540766411282592856903984951653826560)
IPv6Network('2001:db8::/128')</pre>
+
IPv6Network('2001:db8::/128')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
As with addresses, creation of a particular kind of network can be forced
+
与地址一样,可以通过直接调用类构造函数而不是使用工厂函数来强制创建特定类型的网络。
by calling the class constructor directly instead of using the factory
 
function.
 
  
  
第182行: 第142行:
 
<div id="host-interfaces" class="section">
 
<div id="host-interfaces" class="section">
  
=== Host Interfaces ===
+
=== 主机接口 ===
  
As mentioned just above, if you need to describe an address on a particular
+
如上所述,如果您需要描述特定网络上的地址,地址和网络类别都不够。 像 <code>192.0.2.1/24</code> 这样的符号通常被网络工程师和为防火墙和路由器编写工具的人用作“网络 <code>192.0.2.0/24</code> 上的主机 <code>192.0.2.1</code>”的简写,因此,[ X196X]ipaddress 提供了一组将地址与特定网络相关联的混合类。 用于创建的接口与用于定义网络对象的接口相同,只是地址部分不限于网络地址。
network, neither the address nor the network classes are sufficient.
 
Notation like <code>192.0.2.1/24</code> is commonly used by network engineers and the
 
people who write tools for firewalls and routers as shorthand for &quot;the host
 
<code>192.0.2.1</code> on the network <code>192.0.2.0/24</code>&quot;, Accordingly, [[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]]
 
provides a set of hybrid classes that associate an address with a particular
 
network. The interface for creation is identical to that for defining network
 
objects, except that the address portion isn't constrained to being a network
 
address.
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第198行: 第150行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_interface('192.0.2.1/24')
+
<syntaxhighlight lang="python">>>> ipaddress.ip_interface('192.0.2.1/24')
 
IPv4Interface('192.0.2.1/24')
 
IPv4Interface('192.0.2.1/24')
&gt;&gt;&gt; ipaddress.ip_interface('2001:db8::1/96')
+
>>> ipaddress.ip_interface('2001:db8::1/96')
IPv6Interface('2001:db8::1/96')</pre>
+
IPv6Interface('2001:db8::1/96')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Integer inputs are accepted (as with networks), and use of a particular IP
+
接受整数输入(与网络一样),并且可以通过直接调用相关构造函数来强制使用特定 IP 版本。
version can be forced by calling the relevant constructor directly.
 
  
  
第215行: 第166行:
 
<div id="inspecting-address-network-interface-objects" class="section">
 
<div id="inspecting-address-network-interface-objects" class="section">
  
== Inspecting Address/Network/Interface Objects ==
+
== 检查地址/网络/接口对象 ==
  
You've gone to the trouble of creating an IPv(4|6)(Address|Network|Interface)
+
您在创建 IPv(4|6)(Address|Network|Interface) 对象时遇到了麻烦,因此您可能想要获取有关它的信息。 [[../../library/ipaddress#module-ipaddress|ipaddress]] 试图让这件事变得简单而直观。
object, so you probably want to get information about it. [[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]]
 
tries to make doing this easy and intuitive.
 
  
Extracting the IP version:
+
提取IP版本:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第227行: 第176行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; addr4 = ipaddress.ip_address('192.0.2.1')
+
<syntaxhighlight lang="python3">>>> addr4 = ipaddress.ip_address('192.0.2.1')
&gt;&gt;&gt; addr6 = ipaddress.ip_address('2001:db8::1')
+
>>> addr6 = ipaddress.ip_address('2001:db8::1')
&gt;&gt;&gt; addr6.version
+
>>> addr6.version
 
6
 
6
&gt;&gt;&gt; addr4.version
+
>>> addr4.version
4</pre>
+
4</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Obtaining the network from an interface:
+
从接口获取网络:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第243行: 第192行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; host4 = ipaddress.ip_interface('192.0.2.1/24')
+
<syntaxhighlight lang="python3">>>> host4 = ipaddress.ip_interface('192.0.2.1/24')
&gt;&gt;&gt; host4.network
+
>>> host4.network
 
IPv4Network('192.0.2.0/24')
 
IPv4Network('192.0.2.0/24')
&gt;&gt;&gt; host6 = ipaddress.ip_interface('2001:db8::1/96')
+
>>> host6 = ipaddress.ip_interface('2001:db8::1/96')
&gt;&gt;&gt; host6.network
+
>>> host6.network
IPv6Network('2001:db8::/96')</pre>
+
IPv6Network('2001:db8::/96')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Finding out how many individual addresses are in a network:
+
找出网络中有多少个单独的地址:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第259行: 第208行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; net4 = ipaddress.ip_network('192.0.2.0/24')
+
<syntaxhighlight lang="python3">>>> net4 = ipaddress.ip_network('192.0.2.0/24')
&gt;&gt;&gt; net4.num_addresses
+
>>> net4.num_addresses
 
256
 
256
&gt;&gt;&gt; net6 = ipaddress.ip_network('2001:db8::0/96')
+
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
&gt;&gt;&gt; net6.num_addresses
+
>>> net6.num_addresses
4294967296</pre>
+
4294967296</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Iterating through the &quot;usable&quot; addresses on a network:
+
遍历网络上的“可用”地址:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第275行: 第224行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; net4 = ipaddress.ip_network('192.0.2.0/24')
+
<syntaxhighlight lang="python3">>>> net4 = ipaddress.ip_network('192.0.2.0/24')
&gt;&gt;&gt; for x in net4.hosts():
+
>>> for x in net4.hosts():
 
...    print(x)   
 
...    print(x)   
 
192.0.2.1
 
192.0.2.1
第285行: 第234行:
 
192.0.2.252
 
192.0.2.252
 
192.0.2.253
 
192.0.2.253
192.0.2.254</pre>
+
192.0.2.254</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Obtaining the netmask (i.e. set bits corresponding to the network prefix) or
+
获取网络掩码(即 设置对应于网络前缀的位)或主机掩码(不属于网络掩码的任何位):
the hostmask (any bits that are not part of the netmask):
 
  
 
<div class="doctest highlight-default notranslate">
 
<div class="doctest highlight-default notranslate">
第297行: 第245行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; net4 = ipaddress.ip_network('192.0.2.0/24')
+
<syntaxhighlight lang="python">>>> net4 = ipaddress.ip_network('192.0.2.0/24')
&gt;&gt;&gt; net4.netmask
+
>>> net4.netmask
 
IPv4Address('255.255.255.0')
 
IPv4Address('255.255.255.0')
&gt;&gt;&gt; net4.hostmask
+
>>> net4.hostmask
 
IPv4Address('0.0.0.255')
 
IPv4Address('0.0.0.255')
&gt;&gt;&gt; net6 = ipaddress.ip_network('2001:db8::0/96')
+
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
&gt;&gt;&gt; net6.netmask
+
>>> net6.netmask
 
IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
 
IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
&gt;&gt;&gt; net6.hostmask
+
>>> net6.hostmask
IPv6Address('::ffff:ffff')</pre>
+
IPv6Address('::ffff:ffff')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Exploding or compressing the address:
+
分解或压缩地址:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第317行: 第265行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; addr6.exploded
+
<syntaxhighlight lang="python3">>>> addr6.exploded
 
'2001:0db8:0000:0000:0000:0000:0000:0001'
 
'2001:0db8:0000:0000:0000:0000:0000:0001'
&gt;&gt;&gt; addr6.compressed
+
>>> addr6.compressed
 
'2001:db8::1'
 
'2001:db8::1'
&gt;&gt;&gt; net6.exploded
+
>>> net6.exploded
 
'2001:0db8:0000:0000:0000:0000:0000:0000/96'
 
'2001:0db8:0000:0000:0000:0000:0000:0000/96'
&gt;&gt;&gt; net6.compressed
+
>>> net6.compressed
'2001:db8::/96'</pre>
+
'2001:db8::/96'</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
While IPv4 doesn't support explosion or compression, the associated objects
+
虽然 IPv4 不支持扩展或压缩,但关联对象仍提供相关属性,以便版本中立代码可以轻松确保对 IPv6 地址使用最简洁或最详细的形式,同时仍能正确处理 IPv4 地址。
still provide the relevant properties so that version neutral code can
 
easily ensure the most concise or most verbose form is used for IPv6
 
addresses while still correctly handling IPv4 addresses.
 
  
  
第338行: 第283行:
 
<div id="networks-as-lists-of-addresses" class="section">
 
<div id="networks-as-lists-of-addresses" class="section">
  
== Networks as lists of Addresses ==
+
== 作为地址列表的网络 ==
  
It's sometimes useful to treat networks as lists. This means it is possible
+
将网络视为列表有时很有用。 这意味着可以像这样对它们进行索引:
to index them like this:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第347行: 第291行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; net4[1]
+
<syntaxhighlight lang="python3">>>> net4[1]
 
IPv4Address('192.0.2.1')
 
IPv4Address('192.0.2.1')
&gt;&gt;&gt; net4[-1]
+
>>> net4[-1]
 
IPv4Address('192.0.2.255')
 
IPv4Address('192.0.2.255')
&gt;&gt;&gt; net6[1]
+
>>> net6[1]
 
IPv6Address('2001:db8::1')
 
IPv6Address('2001:db8::1')
&gt;&gt;&gt; net6[-1]
+
>>> net6[-1]
IPv6Address('2001:db8::ffff:ffff')</pre>
+
IPv6Address('2001:db8::ffff:ffff')</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
It also means that network objects lend themselves to using the list
+
这也意味着网络对象适合使用这样的列表成员测试语法:
membership test syntax like this:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第366行: 第309行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>if address in network:
+
<syntaxhighlight lang="python3">if address in network:
     # do something</pre>
+
     # do something</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Containment testing is done efficiently based on the network prefix:
+
基于网络前缀有效地完成遏制测试:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第378行: 第321行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; addr4 = ipaddress.ip_address('192.0.2.1')
+
<syntaxhighlight lang="python3">>>> addr4 = ipaddress.ip_address('192.0.2.1')
&gt;&gt;&gt; addr4 in ipaddress.ip_network('192.0.2.0/24')
+
>>> addr4 in ipaddress.ip_network('192.0.2.0/24')
 
True
 
True
&gt;&gt;&gt; addr4 in ipaddress.ip_network('192.0.3.0/24')
+
>>> addr4 in ipaddress.ip_network('192.0.3.0/24')
False</pre>
+
False</syntaxhighlight>
  
 
</div>
 
</div>
第391行: 第334行:
 
<div id="comparisons" class="section">
 
<div id="comparisons" class="section">
  
== Comparisons ==
+
== 比较 ==
  
[[../../library/ipaddress#module-ipaddress|<code>ipaddress</code>]] provides some simple, hopefully intuitive ways to compare
+
[[../../library/ipaddress#module-ipaddress|ipaddress]] 提供了一些简单的、希望直观的方法来比较对象,在那里它是有意义的:
objects, where it makes sense:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第400行: 第342行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_address('192.0.2.1') &lt; ipaddress.ip_address('192.0.2.2')
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_address('192.0.2.1') < ipaddress.ip_address('192.0.2.2')
True</pre>
+
True</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
A [[../../library/exceptions#TypeError|<code>TypeError</code>]] exception is raised if you try to compare objects of
+
如果您尝试比较不同版本或不同类型的对象,则会引发 [[../../library/exceptions#TypeError|TypeError]] 异常。
different versions or different types.
 
  
  
第413行: 第354行:
 
<div id="using-ip-addresses-with-other-modules" class="section">
 
<div id="using-ip-addresses-with-other-modules" class="section">
  
== Using IP Addresses with other modules ==
+
== IP 地址与其他模块一起使用 ==
  
Other modules that use IP addresses (such as [[../../library/socket#module-socket|<code>socket</code>]]) usually won't
+
其他使用 IP 地址的模块(例如 [[../../library/socket#module-socket|socket]])通常不会直接接受来自该模块的对象。 相反,它们必须被强制转换为其他模块将接受的整数或字符串:
accept objects from this module directly. Instead, they must be coerced to
 
an integer or string that the other module will accept:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第423行: 第362行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; addr4 = ipaddress.ip_address('192.0.2.1')
+
<syntaxhighlight lang="python3">>>> addr4 = ipaddress.ip_address('192.0.2.1')
&gt;&gt;&gt; str(addr4)
+
>>> str(addr4)
 
'192.0.2.1'
 
'192.0.2.1'
&gt;&gt;&gt; int(addr4)
+
>>> int(addr4)
3221225985</pre>
+
3221225985</syntaxhighlight>
  
 
</div>
 
</div>
第436行: 第375行:
 
<div id="getting-more-detail-when-instance-creation-fails" class="section">
 
<div id="getting-more-detail-when-instance-creation-fails" class="section">
  
== Getting more detail when instance creation fails ==
+
== 实例创建失败时获取更多详细信息 ==
  
When creating address/network/interface objects using the version-agnostic
+
使用与版本无关的工厂函数创建地址/网络/接口对象时,任何错误都将报告为 [[../../library/exceptions#ValueError|ValueError]] 并带有一般错误消息,仅说明传入的值未被识别为该类型的对象. 缺少特定错误是因为有必要知道值是 ''supposed'' IPv4 还是 IPv6,以便提供有关拒绝的原因的更多详细信息。
factory functions, any errors will be reported as [[../../library/exceptions#ValueError|<code>ValueError</code>]] with
 
a generic error message that simply says the passed in value was not
 
recognized as an object of that type. The lack of a specific error is
 
because it's necessary to know whether the value is ''supposed'' to be IPv4
 
or IPv6 in order to provide more detail on why it has been rejected.
 
  
To support use cases where it is useful to have access to this additional
+
为了支持访问此附加细节有用的用例,各个类构造函数实际上引发了 [[../../library/exceptions#ValueError|ValueError]] 子类 [[../../library/ipaddress#ipaddress|ipaddress.AddressValueError]] [[../../library/ipaddress#ipaddress|ipaddress.NetmaskValueError]]准确指出定义的哪一部分未能正确解析。
detail, the individual class constructors actually raise the
 
[[../../library/exceptions#ValueError|<code>ValueError</code>]] subclasses [[../../library/ipaddress#ipaddress|<code>ipaddress.AddressValueError</code>]] and
 
[[../../library/ipaddress#ipaddress|<code>ipaddress.NetmaskValueError</code>]] to indicate exactly which part of
 
the definition failed to parse correctly.
 
  
The error messages are significantly more detailed when using the
+
直接使用类构造函数时,错误消息要详细得多。 例如:
class constructors directly. For example:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第458行: 第387行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>&gt;&gt;&gt; ipaddress.ip_address(&quot;192.168.0.256&quot;)
+
<syntaxhighlight lang="python3">>>> ipaddress.ip_address("192.168.0.256")
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
   ...
 
   ...
 
ValueError: '192.168.0.256' does not appear to be an IPv4 or IPv6 address
 
ValueError: '192.168.0.256' does not appear to be an IPv4 or IPv6 address
&gt;&gt;&gt; ipaddress.IPv4Address(&quot;192.168.0.256&quot;)
+
>>> ipaddress.IPv4Address("192.168.0.256")
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
   ...
 
   ...
ipaddress.AddressValueError: Octet 256 (&gt; 255) not permitted in '192.168.0.256'
+
ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.0.256'
  
&gt;&gt;&gt; ipaddress.ip_network(&quot;192.168.0.1/64&quot;)
+
>>> ipaddress.ip_network("192.168.0.1/64")
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
   ...
 
   ...
 
ValueError: '192.168.0.1/64' does not appear to be an IPv4 or IPv6 network
 
ValueError: '192.168.0.1/64' does not appear to be an IPv4 or IPv6 network
&gt;&gt;&gt; ipaddress.IPv4Network(&quot;192.168.0.1/64&quot;)
+
>>> ipaddress.IPv4Network("192.168.0.1/64")
 
Traceback (most recent call last):
 
Traceback (most recent call last):
 
   ...
 
   ...
ipaddress.NetmaskValueError: '64' is not a valid netmask</pre>
+
ipaddress.NetmaskValueError: '64' is not a valid netmask</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
However, both of the module specific exceptions have [[../../library/exceptions#ValueError|<code>ValueError</code>]] as their
+
但是,这两个特定于模块的异常都将 [[../../library/exceptions#ValueError|ValueError]] 作为它们的父类,因此如果您不关心特定类型的错误,您仍然可以编写如下代码:
parent class, so if you're not concerned with the particular type of error,
 
you can still write code like the following:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第487行: 第414行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>try:
+
<syntaxhighlight lang="python3">try:
 
     network = ipaddress.IPv4Network(address)
 
     network = ipaddress.IPv4Network(address)
 
except ValueError:
 
except ValueError:
     print('address/netmask is invalid for IPv4:', address)</pre>
+
     print('address/netmask is invalid for IPv4:', address)</syntaxhighlight>
  
 
</div>
 
</div>
第499行: 第426行:
  
 
</div>
 
</div>
 +
<div class="clearer">
  
[[Category:Python 3.9 中文文档]]
+
 
 +
 
 +
</div>
 +
 
 +
[[Category:Python 3.9 文档]]

2021年10月31日 (日) 04:50的最新版本

ipaddress 模块介绍

作者
彼得·穆迪
作者
尼克·科格兰

概述

本文档旨在简要介绍 ipaddress 模块。 它主要针对不熟悉 IP 网络术语的用户,但对于想要了解 ipaddress 如何表示 IP 网络寻址概念的网络工程师也可能有用。


创建地址/网络/接口对象

由于 ipaddress 是一个用于检查和操作 IP 地址的模块,因此您要做的第一件事就是创建一些对象。 您可以使用 ipaddress 从字符串和整数创建对象。

关于 IP 版本的说明

对于不是特别熟悉 IP 寻址的读者,重要的是要知道 Internet 协议目前正在从协议的第 4 版迁移到第 6 版。 这种转变的发生主要是因为该协议的第 4 版没有提供足够的地址来满足全世界的需求,特别是考虑到直接连接到互联网的设备数量不断增加。

详细解释两个版本的协议差异超出了本介绍的范围,但读者至少需要意识到这两个版本的存在,并且有时需要强制使用一个版本或其他。


IP 主机地址

地址,通常称为“主机地址”,是使用 IP 寻址时最基本的单位。 创建地址最简单的方法是使用 ipaddress.ip_address() 工厂函数,它会根据传入的值自动确定是创建 IPv4 还是 IPv6 地址:

>>> ipaddress.ip_address('192.0.2.1')
IPv4Address('192.0.2.1')
>>> ipaddress.ip_address('2001:DB8::1')
IPv6Address('2001:db8::1')

地址也可以直接从整数创建。 将适合 32 位的值假定为 IPv4 地址:

>>> ipaddress.ip_address(3221225985)
IPv4Address('192.0.2.1')
>>> ipaddress.ip_address(42540766411282592856903984951653826561)
IPv6Address('2001:db8::1')

要强制使用 IPv4 或 IPv6 地址,可以直接调用相关类。 这对于强制为小整数创建 IPv6 地址特别有用:

>>> ipaddress.ip_address(1)
IPv4Address('0.0.0.1')
>>> ipaddress.IPv4Address(1)
IPv4Address('0.0.0.1')
>>> ipaddress.IPv6Address(1)
IPv6Address('::1')

定义网络

主机地址通常组合到 IP 网络中,因此 ipaddress 提供了一种创建、检查和操作网络定义的方法。 IP 网络对象由定义作为该网络一部分的主机地址范围的字符串构成。 该信息的最简单形式是“网络地址/网络前缀”对,其中前缀定义了前导位的数量,用于确定地址是否是网络的一部分,网络地址定义了预期值那些位。

至于地址,提供了一个工厂函数,可以自动确定正确的 IP 版本:

>>> ipaddress.ip_network('192.0.2.0/24')
IPv4Network('192.0.2.0/24')
>>> ipaddress.ip_network('2001:db8::0/96')
IPv6Network('2001:db8::/96')

网络对象不能设置任何主机位。 这样做的实际效果是 192.0.2.1/24 没有描述网络。 此类定义被称为接口对象,因为 ip-on-a-network 表示法通常用于描述给定网络上计算机的网络接口,并在下一节中进一步描述。

默认情况下,尝试创建设置了主机位的网络对象将导致引发 ValueError。 要请求将附加位强制为零,可以将标志 strict=False 传递给构造函数:

>>> ipaddress.ip_network('192.0.2.1/24')
Traceback (most recent call last):
   ...
ValueError: 192.0.2.1/24 has host bits set
>>> ipaddress.ip_network('192.0.2.1/24', strict=False)
IPv4Network('192.0.2.0/24')

虽然字符串形式提供了更大的灵活性,但网络也可以用整数定义,就像主机地址一样。 在这种情况下,网络被认为只包含由整数标识的单个地址,因此网络前缀包括整个网络地址:

>>> ipaddress.ip_network(3221225984)
IPv4Network('192.0.2.0/32')
>>> ipaddress.ip_network(42540766411282592856903984951653826560)
IPv6Network('2001:db8::/128')

与地址一样,可以通过直接调用类构造函数而不是使用工厂函数来强制创建特定类型的网络。


主机接口

如上所述,如果您需要描述特定网络上的地址,地址和网络类别都不够。 像 192.0.2.1/24 这样的符号通常被网络工程师和为防火墙和路由器编写工具的人用作“网络 192.0.2.0/24 上的主机 192.0.2.1”的简写,因此,[ X196X]ipaddress 提供了一组将地址与特定网络相关联的混合类。 用于创建的接口与用于定义网络对象的接口相同,只是地址部分不限于网络地址。

>>> ipaddress.ip_interface('192.0.2.1/24')
IPv4Interface('192.0.2.1/24')
>>> ipaddress.ip_interface('2001:db8::1/96')
IPv6Interface('2001:db8::1/96')

接受整数输入(与网络一样),并且可以通过直接调用相关构造函数来强制使用特定 IP 版本。


检查地址/网络/接口对象

您在创建 IPv(4|6)(Address|Network|Interface) 对象时遇到了麻烦,因此您可能想要获取有关它的信息。 ipaddress 试图让这件事变得简单而直观。

提取IP版本:

>>> addr4 = ipaddress.ip_address('192.0.2.1')
>>> addr6 = ipaddress.ip_address('2001:db8::1')
>>> addr6.version
6
>>> addr4.version
4

从接口获取网络:

>>> host4 = ipaddress.ip_interface('192.0.2.1/24')
>>> host4.network
IPv4Network('192.0.2.0/24')
>>> host6 = ipaddress.ip_interface('2001:db8::1/96')
>>> host6.network
IPv6Network('2001:db8::/96')

找出网络中有多少个单独的地址:

>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> net4.num_addresses
256
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
>>> net6.num_addresses
4294967296

遍历网络上的“可用”地址:

>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> for x in net4.hosts():
...     print(x)  
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
...
192.0.2.252
192.0.2.253
192.0.2.254

获取网络掩码(即 设置对应于网络前缀的位)或主机掩码(不属于网络掩码的任何位):

>>> net4 = ipaddress.ip_network('192.0.2.0/24')
>>> net4.netmask
IPv4Address('255.255.255.0')
>>> net4.hostmask
IPv4Address('0.0.0.255')
>>> net6 = ipaddress.ip_network('2001:db8::0/96')
>>> net6.netmask
IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::')
>>> net6.hostmask
IPv6Address('::ffff:ffff')

分解或压缩地址:

>>> addr6.exploded
'2001:0db8:0000:0000:0000:0000:0000:0001'
>>> addr6.compressed
'2001:db8::1'
>>> net6.exploded
'2001:0db8:0000:0000:0000:0000:0000:0000/96'
>>> net6.compressed
'2001:db8::/96'

虽然 IPv4 不支持扩展或压缩,但关联对象仍提供相关属性,以便版本中立代码可以轻松确保对 IPv6 地址使用最简洁或最详细的形式,同时仍能正确处理 IPv4 地址。


作为地址列表的网络

将网络视为列表有时很有用。 这意味着可以像这样对它们进行索引:

>>> net4[1]
IPv4Address('192.0.2.1')
>>> net4[-1]
IPv4Address('192.0.2.255')
>>> net6[1]
IPv6Address('2001:db8::1')
>>> net6[-1]
IPv6Address('2001:db8::ffff:ffff')

这也意味着网络对象适合使用这样的列表成员测试语法:

if address in network:
    # do something

基于网络前缀有效地完成遏制测试:

>>> addr4 = ipaddress.ip_address('192.0.2.1')
>>> addr4 in ipaddress.ip_network('192.0.2.0/24')
True
>>> addr4 in ipaddress.ip_network('192.0.3.0/24')
False

比较

ipaddress 提供了一些简单的、希望直观的方法来比较对象,在那里它是有意义的:

>>> ipaddress.ip_address('192.0.2.1') < ipaddress.ip_address('192.0.2.2')
True

如果您尝试比较不同版本或不同类型的对象,则会引发 TypeError 异常。


将 IP 地址与其他模块一起使用

其他使用 IP 地址的模块(例如 socket)通常不会直接接受来自该模块的对象。 相反,它们必须被强制转换为其他模块将接受的整数或字符串:

>>> addr4 = ipaddress.ip_address('192.0.2.1')
>>> str(addr4)
'192.0.2.1'
>>> int(addr4)
3221225985

实例创建失败时获取更多详细信息

使用与版本无关的工厂函数创建地址/网络/接口对象时,任何错误都将报告为 ValueError 并带有一般错误消息,仅说明传入的值未被识别为该类型的对象. 缺少特定错误是因为有必要知道值是 supposed 是 IPv4 还是 IPv6,以便提供有关拒绝的原因的更多详细信息。

为了支持访问此附加细节有用的用例,各个类构造函数实际上引发了 ValueError 子类 ipaddress.AddressValueErroripaddress.NetmaskValueError准确指出定义的哪一部分未能正确解析。

直接使用类构造函数时,错误消息要详细得多。 例如:

>>> ipaddress.ip_address("192.168.0.256")
Traceback (most recent call last):
  ...
ValueError: '192.168.0.256' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.IPv4Address("192.168.0.256")
Traceback (most recent call last):
  ...
ipaddress.AddressValueError: Octet 256 (> 255) not permitted in '192.168.0.256'

>>> ipaddress.ip_network("192.168.0.1/64")
Traceback (most recent call last):
  ...
ValueError: '192.168.0.1/64' does not appear to be an IPv4 or IPv6 network
>>> ipaddress.IPv4Network("192.168.0.1/64")
Traceback (most recent call last):
  ...
ipaddress.NetmaskValueError: '64' is not a valid netmask

但是,这两个特定于模块的异常都将 ValueError 作为它们的父类,因此如果您不关心特定类型的错误,您仍然可以编写如下代码:

try:
    network = ipaddress.IPv4Network(address)
except ValueError:
    print('address/netmask is invalid for IPv4:', address)