mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
25 lines
46 KiB
HTML
25 lines
46 KiB
HTML
<div class="body" role="main"><div class="section" id="module-struct"><h1><span class="yiyi-st" id="yiyi-10">7.1. <a class="reference internal" href="#module-struct" title="struct: Interpret bytes as packed binary data."><code class="xref py py-mod docutils literal"><span class="pre">struct</span></code></a> — 字节码与二进制数据之间的转换</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/struct.py">Lib / struct.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">该模块执行Python值和以Python <a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>表示的C结构体之间的转换,</span><span class="yiyi-st" id="yiyi-13">这可以用于处理存储在文件中或来自网络连接以及其他源的二进制数据。</span><span class="yiyi-st" id="yiyi-14">它使用<a class="reference internal" href="#struct-format-strings"><span>一定格式的字符串</span></a>作为C语言结构布局的简洁描述以及到或从Python值的预期转换。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-15">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-16">默认情况下,封装给定C结构的结果包括填充字节,以便为所涉及的C类型保持适当的对齐;类似地,当分离时考虑对准。</span><span class="yiyi-st" id="yiyi-17">选择此行为以使打包结构的字节完全对应于C结构在存储器中的布局。</span><span class="yiyi-st" id="yiyi-18">要处理平台无关的数据格式或省略隐式填充字节,请使用<code class="docutils literal"><span class="pre">标准</span></code>大小和对齐而不是<code class="docutils literal"><span class="pre">原生</span></code>大小和对齐方式:请参阅<a class="reference internal" href="#struct-alignment"><span>字节顺序,大小和对齐</span></a>了解详情。</span></p></div><p><span class="yiyi-st" id="yiyi-19">几个<a class="reference internal" href="#module-struct" title="struct: Interpret bytes as packed binary data."><code class="xref py py-mod docutils literal"><span class="pre">struct</span></code></a>函数(和<a class="reference internal" href="#struct.Struct" title="struct.Struct"><code class="xref py py-class docutils literal"><span class="pre">Struct</span></code></a>的方法)接受一个<em>缓冲</em>参数。</span><span class="yiyi-st" id="yiyi-20">这是指实现<a class="reference internal" href="../c-api/buffer.html#bufferobjects"><span>Buffer Protocol</span></a>并提供可读或可读写缓冲区的对象。</span><span class="yiyi-st" id="yiyi-21">用于该目的的最常见类型是<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>和<a class="reference internal" href="functions.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal"><span class="pre">bytearray</span></code></a>,但是可以看作是字节数组的许多其他类型实现缓冲区协议,因此它们可以读/填充,而不需要从<a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a>对象进行附加复制。</span></p><div class="section" id="functions-and-exceptions"><h2><span class="yiyi-st" id="yiyi-22">7.1.1.</span><span class="yiyi-st" id="yiyi-23">函数和异常</span></h2><p><span class="yiyi-st" id="yiyi-24">该模块定义了以下异常和函数:</span></p><dl class="exception"><dt id="struct.error"><span class="yiyi-st" id="yiyi-25"><em class="property">exception </em><code class="descclassname">struct.</code><code class="descname">error</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-26">在各种场合提出异议;参数是描述错误的字符串。</span></p></dd></dl><dl class="function"><dt id="struct.pack"><span class="yiyi-st" id="yiyi-27"><code class="descclassname">struct.</code><code class="descname">pack</code><span class="sig-paren">(</span><em>fmt</em>, <em>v1</em>, <em>v2</em>, <em>...</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-28">Return a bytes object containing the values <em>v1</em>, <em>v2</em>, ... packed according to the format string <em>fmt</em>.</span><span class="yiyi-st" id="yiyi-29">参数必须与格式所需的值完全匹配。</span></p></dd></dl><dl class="function"><dt id="struct.pack_into"><span class="yiyi-st" id="yiyi-30"><code class="descclassname">struct.</code><code class="descname">pack_into</code><span class="sig-paren">(</span><em>fmt</em>, <em>buffer</em>, <em>offset</em>, <em>v1</em>, <em>v2</em>, <em>...</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-31">根据格式字符串<em>fmt</em>封装值<em>v1</em>,<em>v2</em>,并将压缩字节写入可写缓冲区<em>缓冲区</em>从位置<em>偏移</em>开始。</span><span class="yiyi-st" id="yiyi-32">请注意,<em>offset</em>是必需的参数。</span></p></dd></dl><dl class="function"><dt id="struct.unpack"><span class="yiyi-st" id="yiyi-33"><code class="descclassname">struct.</code><code class="descname">unpack</code><span class="sig-paren">(</span><em>fmt</em>, <em>buffer</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-34">从缓冲器<em>缓冲器</em>分离(假定由<code class="docutils literal"><span class="pre">pack(fmt,</span> <span class="pre">...)</span> 格式字符串<em>fmt</em>。</code></span><span class="yiyi-st" id="yiyi-35">结果是一个元组,即使它只包含一个项目。</span><span class="yiyi-st" id="yiyi-36">缓冲区的大小(以字节为单位)必须与格式所需的大小匹配,如<a class="reference internal" href="#struct.calcsize" title="struct.calcsize"><code class="xref py py-func docutils literal"><span class="pre">calcsize()</span></code></a>所反映。</span></p></dd></dl><dl class="function"><dt id="struct.unpack_from"><span class="yiyi-st" id="yiyi-37"><code class="descclassname">struct.</code><code class="descname">unpack_from</code><span class="sig-paren">(</span><em>fmt</em>, <em>buffer</em>, <em>offset=0</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-38">根据格式字符串<em>fmt</em>从<em>缓冲区</em>开始分离<em>偏移</em>。</span><span class="yiyi-st" id="yiyi-39">结果是一个元组,即使它只包含一个项目。</span><span class="yiyi-st" id="yiyi-40">缓冲区的大小(以字节为单位,减去<em>offset</em>)必须至少为格式所需的大小,如<a class="reference internal" href="#struct.calcsize" title="struct.calcsize"><code class="xref py py-func docutils literal"><span class="pre">calcsize()</span></code></a>所示。</span></p></dd></dl><dl class="function"><dt id="struct.iter_unpack"><span class="yiyi-st" id="yiyi-41"><code class="descclassname">struct.</code><code class="descname">iter_unpack</code><span class="sig-paren">(</span><em>fmt</em>, <em>buffer</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-42">根据格式字符串<em>fmt</em>从缓冲区<em>缓冲区</em>中迭代分离。</span><span class="yiyi-st" id="yiyi-43">此函数返回一个迭代器,它将从缓冲区读取大小相等的块,直到其所有内容都已用完。</span><span class="yiyi-st" id="yiyi-44">缓冲区的大小(以字节为单位)必须是格式所需大小的倍数,如<a class="reference internal" href="#struct.calcsize" title="struct.calcsize"><code class="xref py py-func docutils literal"><span class="pre">calcsize()</span></code></a>所反映。</span></p><p><span class="yiyi-st" id="yiyi-45">每次迭代产生由格式字符串指定的元组。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-46"><span class="versionmodified">版本3.4中的新功能。</span></span></p></div></dd></dl><dl class="function"><dt id="struct.calcsize"><span class="yiyi-st" id="yiyi-47"><code class="descclassname">struct.</code><code class="descname">calcsize</code><span class="sig-paren">(</span><em>fmt</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-48">返回对应于格式字符串的结构(以及由此产生的<code class="docutils literal"><span class="pre">pack(fmt,</span> <span class="pre">...)</span></code>)的字节对象的大小<em>fmt</em>。</span></p></dd></dl></div><div class="section" id="format-strings"><h2><span class="yiyi-st" id="yiyi-49">7.1.2.</span><span class="yiyi-st" id="yiyi-50">格式字符串</span></h2><p><span class="yiyi-st" id="yiyi-51">格式字符串是用于在封装和分拆数据时指定预期布局的机制。</span><span class="yiyi-st" id="yiyi-52">它们由<a class="reference internal" href="#format-characters"><span>Format Characters</span></a>构成,它指定正在打包/解包的数据类型。</span><span class="yiyi-st" id="yiyi-53">此外,还有一些特殊字符用于控制<a class="reference internal" href="#struct-alignment"><span>Byte Order, Size, and Alignment</span></a>。</span></p><div class="section" id="byte-order-size-and-alignment"><h3><span class="yiyi-st" id="yiyi-54">7.1.2.1.</span><span class="yiyi-st" id="yiyi-55">字节顺序,大小和对齐</span></h3><p><span class="yiyi-st" id="yiyi-56">默认情况下,C类型以机器的本机格式和字节顺序表示,并且如果必要,通过跳过填充字节(根据C编译器使用的规则)正确对齐。</span></p><p><span class="yiyi-st" id="yiyi-57">或者,根据下表,格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐:</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-58">字符</span></th><th class="head"><span class="yiyi-st" id="yiyi-59">字节顺序</span></th><th class="head"><span class="yiyi-st" id="yiyi-60">尺寸</span></th><th class="head"><span class="yiyi-st" id="yiyi-61">对准</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-62"><code class="docutils literal"><span class="pre">@</span></code></span></td><td><span class="yiyi-st" id="yiyi-63">本机</span></td><td><span class="yiyi-st" id="yiyi-64">本机</span></td><td><span class="yiyi-st" id="yiyi-65">本机</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-66"><code class="docutils literal"><span class="pre">=</span></code></span></td><td><span class="yiyi-st" id="yiyi-67">本机</span></td><td><span class="yiyi-st" id="yiyi-68">标准</span></td><td><span class="yiyi-st" id="yiyi-69">没有</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-70"><code class="docutils literal"><span class="pre"><</span></code></span></td><td><span class="yiyi-st" id="yiyi-71">小端</span></td><td><span class="yiyi-st" id="yiyi-72">标准</span></td><td><span class="yiyi-st" id="yiyi-73">没有</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-74"><code class="docutils literal"><span class="pre">></span></code></span></td><td><span class="yiyi-st" id="yiyi-75">大端</span></td><td><span class="yiyi-st" id="yiyi-76">标准</span></td><td><span class="yiyi-st" id="yiyi-77">没有</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-78"><code class="docutils literal"><span class="pre">!</span></code></span></td><td><span class="yiyi-st" id="yiyi-79">network(= big-endian)</span></td><td><span class="yiyi-st" id="yiyi-80">标准</span></td><td><span class="yiyi-st" id="yiyi-81">没有</span></td></tr></tbody></table><p><span class="yiyi-st" id="yiyi-82">如果第一个字符不是其中之一,则假定为<code class="docutils literal"><span class="pre">'@'</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-83">本地字节顺序是大端或小端,取决于主机系统。</span><span class="yiyi-st" id="yiyi-84">例如,Intel x86和AMD64(x86-64)是小端字节序;摩托罗拉68000和PowerPC G5是大端; ARM和Intel Itanium特性可切换字节顺序(双字节顺序)。</span><span class="yiyi-st" id="yiyi-85">使用<code class="docutils literal"><span class="pre">sys.byteorder</span></code>来检查系统的字节序。</span></p><p><span class="yiyi-st" id="yiyi-86">本机大小和对齐使用C编译器的<code class="docutils literal"><span class="pre">sizeof</span></code>表达式确定。</span><span class="yiyi-st" id="yiyi-87">这总是与本地字节顺序组合。</span></p><p><span class="yiyi-st" id="yiyi-88">标准大小仅取决于格式字符;请参阅<a class="reference internal" href="#format-characters"><span>Format Characters</span></a>部分中的表格。</span></p><p><span class="yiyi-st" id="yiyi-89">注意<code class="docutils literal"><span class="pre">'@'</span></code>和<code class="docutils literal"><span class="pre">'='</span></code>之间的区别:两者都使用本地字节顺序,但是后者的大小和对齐是标准化的。</span></p><p><span class="yiyi-st" id="yiyi-90">格式<code class="docutils literal"><span class="pre">'!'</span></code></span><span class="yiyi-st" id="yiyi-91">是给那些声称自己记不住网络字节顺序是大端还是小端的可怜虫准备的。</span></p><p><span class="yiyi-st" id="yiyi-92">There is no way to indicate non-native byte order (force byte-swapping); use the appropriate choice of <code class="docutils literal"><span class="pre">'<'</span></code> or <code class="docutils literal"><span class="pre">'>'</span></code>.</span></p><p><span class="yiyi-st" id="yiyi-93">笔记:</span></p><ol class="arabic simple"><li><span class="yiyi-st" id="yiyi-94">填充仅在连续的结构成员之间自动添加。</span><span class="yiyi-st" id="yiyi-95">在编码结构的开始或结尾处不添加填充。</span></li><li><span class="yiyi-st" id="yiyi-96">当使用非本地大小和对齐时,不添加填充。</span><span class="yiyi-st" id="yiyi-97">用'','='和'!'。</span></li><li><span class="yiyi-st" id="yiyi-98">要将结构的末端与特定类型的对齐要求对齐,请使用重复计数为零的该类型的代码结束格式。</span><span class="yiyi-st" id="yiyi-99">请参见<a class="reference internal" href="#struct-examples"><span>Examples</span></a>。</span></li></ol></div><div class="section" id="format-characters"><h3><span class="yiyi-st" id="yiyi-100">7.1.2.2.</span><span class="yiyi-st" id="yiyi-101">格式字符</span></h3><p><span class="yiyi-st" id="yiyi-102">格式字符具有以下含义; C和Python值之间的转换应该是显而易见的,因为它们的类型。</span><span class="yiyi-st" id="yiyi-103">The ‘Standard size’ column refers to the size of the packed value in bytes when using standard size; that is, when the format string starts with one of <code class="docutils literal"><span class="pre">'<'</span></code>, <code class="docutils literal"><span class="pre">'>'</span></code>, <code class="docutils literal"><span class="pre">'!'</span></code></span><span class="yiyi-st" id="yiyi-104">或<code class="docutils literal"><span class="pre">'='</span></code>。</span><span class="yiyi-st" id="yiyi-105">当使用原生大小时,打包值的大小取决于平台。</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-106">格式</span></th><th class="head"><span class="yiyi-st" id="yiyi-107">C类型</span></th><th class="head"><span class="yiyi-st" id="yiyi-108">Python类型</span></th><th class="head"><span class="yiyi-st" id="yiyi-109">标准尺寸</span></th><th class="head"><span class="yiyi-st" id="yiyi-110">笔记</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-111"><code class="docutils literal"><span class="pre">x</span></code></span></td><td><span class="yiyi-st" id="yiyi-112">填充字节</span></td><td><span class="yiyi-st" id="yiyi-113">没有值</span></td><td></td><td></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-114"><code class="docutils literal"><span class="pre">c</span></code></span></td><td><span class="yiyi-st" id="yiyi-115"><code class="xref c c-type docutils literal"><span class="pre">char</span></code></span></td><td><span class="yiyi-st" id="yiyi-116">字节长度为1</span></td><td><span class="yiyi-st" id="yiyi-117">1</span></td><td></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-118"><code class="docutils literal"><span class="pre">b</span></code></span></td><td><span class="yiyi-st" id="yiyi-119"><code class="xref c c-type docutils literal"><span class="pre">signed</span> <span class="pre">char</span></code></span></td><td><span class="yiyi-st" id="yiyi-120">整数</span></td><td><span class="yiyi-st" id="yiyi-121">1</span></td><td><span class="yiyi-st" id="yiyi-122">(1),(3)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-123"><code class="docutils literal"><span class="pre">B</span></code></span></td><td><span class="yiyi-st" id="yiyi-124"><code class="xref c c-type docutils literal"><span class="pre">unsigned</span> <span class="pre">char</span></code></span></td><td><span class="yiyi-st" id="yiyi-125">整数</span></td><td><span class="yiyi-st" id="yiyi-126">1</span></td><td><span class="yiyi-st" id="yiyi-127">(3)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-128"><code class="docutils literal"><span class="pre">?</span></code></span></td><td><span class="yiyi-st" id="yiyi-129"><code class="xref c c-type docutils literal"><span class="pre">_Bool</span></code></span></td><td><span class="yiyi-st" id="yiyi-130">bool</span></td><td><span class="yiyi-st" id="yiyi-131">1</span></td><td><span class="yiyi-st" id="yiyi-132">(1)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-133"><code class="docutils literal"><span class="pre">h</span></code></span></td><td><span class="yiyi-st" id="yiyi-134"><code class="xref c c-type docutils literal"><span class="pre">short</span></code></span></td><td><span class="yiyi-st" id="yiyi-135">整数</span></td><td><span class="yiyi-st" id="yiyi-136">2</span></td><td><span class="yiyi-st" id="yiyi-137">(3)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-138"><code class="docutils literal"><span class="pre">H</span></code></span></td><td><span class="yiyi-st" id="yiyi-139"><code class="xref c c-type docutils literal"><span class="pre">unsigned</span> <span class="pre">short</span></code></span></td><td><span class="yiyi-st" id="yiyi-140">整数</span></td><td><span class="yiyi-st" id="yiyi-141">2</span></td><td><span class="yiyi-st" id="yiyi-142">(3)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-143"><code class="docutils literal"><span class="pre">i</span></code></span></td><td><span class="yiyi-st" id="yiyi-144"><code class="xref c c-type docutils literal"><span class="pre">int</span></code></span></td><td><span class="yiyi-st" id="yiyi-145">整数</span></td><td><span class="yiyi-st" id="yiyi-146">4</span></td><td><span class="yiyi-st" id="yiyi-147">(3)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-148"><code class="docutils literal"><span class="pre">I</span></code></span></td><td><span class="yiyi-st" id="yiyi-149"><code class="xref c c-type docutils literal"><span class="pre">unsigned</span> <span class="pre">int</span></code></span></td><td><span class="yiyi-st" id="yiyi-150">整数</span></td><td><span class="yiyi-st" id="yiyi-151">4</span></td><td><span class="yiyi-st" id="yiyi-152">(3)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-153"><code class="docutils literal"><span class="pre">l</span></code></span></td><td><span class="yiyi-st" id="yiyi-154"><code class="xref c c-type docutils literal"><span class="pre">long</span></code></span></td><td><span class="yiyi-st" id="yiyi-155">整数</span></td><td><span class="yiyi-st" id="yiyi-156">4</span></td><td><span class="yiyi-st" id="yiyi-157">(3)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-158"><code class="docutils literal"><span class="pre">L</span></code></span></td><td><span class="yiyi-st" id="yiyi-159"><code class="xref c c-type docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span></code></span></td><td><span class="yiyi-st" id="yiyi-160">整数</span></td><td><span class="yiyi-st" id="yiyi-161">4</span></td><td><span class="yiyi-st" id="yiyi-162">(3)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-163"><code class="docutils literal"><span class="pre">q</span></code></span></td><td><span class="yiyi-st" id="yiyi-164"><code class="xref c c-type docutils literal"><span class="pre">long</span> <span class="pre">long</span></code></span></td><td><span class="yiyi-st" id="yiyi-165">整数</span></td><td><span class="yiyi-st" id="yiyi-166">8</span></td><td><span class="yiyi-st" id="yiyi-167">(2),(3)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-168"><code class="docutils literal"><span class="pre">Q</span></code></span></td><td><span class="yiyi-st" id="yiyi-169"><code class="xref c c-type docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">long</span></code></span></td><td><span class="yiyi-st" id="yiyi-170">整数</span></td><td><span class="yiyi-st" id="yiyi-171">8</span></td><td><span class="yiyi-st" id="yiyi-172">(2),(3)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-173"><code class="docutils literal"><span class="pre">n</span></code></span></td><td><span class="yiyi-st" id="yiyi-174"><code class="xref c c-type docutils literal"><span class="pre">ssize_t</span></code></span></td><td><span class="yiyi-st" id="yiyi-175">整数</span></td><td></td><td><span class="yiyi-st" id="yiyi-176">(4)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-177"><code class="docutils literal"><span class="pre">N</span></code></span></td><td><span class="yiyi-st" id="yiyi-178"><code class="xref c c-type docutils literal"><span class="pre">size_t</span></code></span></td><td><span class="yiyi-st" id="yiyi-179">整数</span></td><td></td><td><span class="yiyi-st" id="yiyi-180">(4)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-181"><code class="docutils literal"><span class="pre">f</span></code></span></td><td><span class="yiyi-st" id="yiyi-182"><code class="xref c c-type docutils literal"><span class="pre">float</span></code></span></td><td><span class="yiyi-st" id="yiyi-183">浮动</span></td><td><span class="yiyi-st" id="yiyi-184">4</span></td><td><span class="yiyi-st" id="yiyi-185">(5)</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-186"><code class="docutils literal"><span class="pre">d</span></code></span></td><td><span class="yiyi-st" id="yiyi-187"><code class="xref c c-type docutils literal"><span class="pre">double</span></code></span></td><td><span class="yiyi-st" id="yiyi-188">浮动</span></td><td><span class="yiyi-st" id="yiyi-189">8</span></td><td><span class="yiyi-st" id="yiyi-190">(5)</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-191"><code class="docutils literal"><span class="pre">s</span></code></span></td><td><span class="yiyi-st" id="yiyi-192"><code class="xref c c-type docutils literal"><span class="pre">char[]</span></code></span></td><td><span class="yiyi-st" id="yiyi-193">字节</span></td><td></td><td></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-194"><code class="docutils literal"><span class="pre">p</span></code></span></td><td><span class="yiyi-st" id="yiyi-195"><code class="xref c c-type docutils literal"><span class="pre">char[]</span></code></span></td><td><span class="yiyi-st" id="yiyi-196">字节</span></td><td></td><td></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-197"><code class="docutils literal"><span class="pre">P</span></code></span></td><td><span class="yiyi-st" id="yiyi-198"><code class="xref c c-type docutils literal"><span class="pre">void</span> <span class="pre">*</span></code></span></td><td><span class="yiyi-st" id="yiyi-199">整数</span></td><td></td><td><span class="yiyi-st" id="yiyi-200">(6)</span></td></tr></tbody></table><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-201"><span class="versionmodified">在版本3.3中已更改:</span>添加了对<code class="docutils literal"><span class="pre">'n'</span></code>和<code class="docutils literal"><span class="pre">'N'</span></code>格式的支持。</span></p></div><p><span class="yiyi-st" id="yiyi-202">笔记:</span></p><ol class="arabic"><li><p class="first"><span class="yiyi-st" id="yiyi-203"><code class="docutils literal"><span class="pre">'?'</span></code></span><span class="yiyi-st" id="yiyi-204">转换代码对应于由C99定义的<code class="xref c c-type docutils literal"><span class="pre">_Bool</span></code>类型。</span><span class="yiyi-st" id="yiyi-205">如果此类型不可用,则使用<code class="xref c c-type docutils literal"><span class="pre">char</span></code>来模拟。</span><span class="yiyi-st" id="yiyi-206">在标准模式下,它总是由一个字节表示。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-207">The <code class="docutils literal"><span class="pre">'q'</span></code> and <code class="docutils literal"><span class="pre">'Q'</span></code> conversion codes are available in native mode only if the platform C compiler supports C <code class="xref c c-type docutils literal"><span class="pre">long</span> <span class="pre">long</span></code>, or, on Windows, <code class="xref c c-type docutils literal"><span class="pre">__int64</span></code>. </span><span class="yiyi-st" id="yiyi-208">它们总是在标准模式下可用。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-209">当尝试使用任何整数转换代码封装非整数时,如果非整数具有<a class="reference internal" href="../reference/datamodel.html#object.__index__" title="object.__index__"><code class="xref py py-meth docutils literal"><span class="pre">__index__()</span></code></a>方法,则在封装之前调用该方法将参数转换为整数。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-210"><span class="versionmodified">在版本3.2中更改:</span>对于非整数的<a class="reference internal" href="../reference/datamodel.html#object.__index__" title="object.__index__"><code class="xref py py-meth docutils literal"><span class="pre">__index__()</span></code></a>方法的使用在3.2中是新的。</span></p></div></li><li><p class="first"><span class="yiyi-st" id="yiyi-211"><code class="docutils literal"><span class="pre">'n'</span></code>和<code class="docutils literal"><span class="pre">'N'</span></code>转换代码仅适用于原始大小(选择为默认值或使用<code class="docutils literal"><span class="pre">'@'</span></code>字节顺序字符)。</span><span class="yiyi-st" id="yiyi-212">对于标准大小,您可以使用适合您的应用程序的其他整数格式。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-213">对于<code class="docutils literal"><span class="pre">'f'</span></code>和<code class="docutils literal"><span class="pre">'d'</span></code>转换代码,打包表示使用IEEE 754 binary32(<code class="docutils literal"><span class="pre">'f'</span></code>)或binary64 for <code class="docutils literal"><span class="pre">'d'</span></code>)格式,而不考虑平台使用的浮点格式。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-214"><code class="docutils literal"><span class="pre">'P'</span></code>格式字符仅适用于本机字节排序(选为默认值或使用<code class="docutils literal"><span class="pre">'@'</span></code>字节顺序字符)。</span><span class="yiyi-st" id="yiyi-215">字节顺序字符<code class="docutils literal"><span class="pre">'='</span></code>选择基于主机系统使用小端或大端排序。</span><span class="yiyi-st" id="yiyi-216">struct模块不会将其解释为本地排序,因此<code class="docutils literal"><span class="pre">'P'</span></code>格式不可用。</span></p></li></ol><p><span class="yiyi-st" id="yiyi-217">格式字符可以在整数重复计数之前。</span><span class="yiyi-st" id="yiyi-218">例如,格式字符串<code class="docutils literal"><span class="pre">'4h'</span></code>的含义与<code class="docutils literal"><span class="pre">'hhhh'</span></code>完全相同。</span></p><p><span class="yiyi-st" id="yiyi-219">忽略格式之间的空格字符;一个计数和它的格式不能包含空格。</span></p><p><span class="yiyi-st" id="yiyi-220">对于<code class="docutils literal"><span class="pre">'s'</span></code>格式字符,计数被解释为字节的长度,而不是其他格式字符的重复计数;例如,<code class="docutils literal"><span class="pre">'10s'</span></code>表示单个10字节字符串,而<code class="docutils literal"><span class="pre">'10c'</span></code>表示10个字符。</span><span class="yiyi-st" id="yiyi-221">如果未给出计数,则默认为1。</span><span class="yiyi-st" id="yiyi-222">对于封装,字符串被截断或填充空字节,以使其适合。</span><span class="yiyi-st" id="yiyi-223">对于分拆,生成的字节对象总是具有指定的字节数。</span><span class="yiyi-st" id="yiyi-224">作为特殊情况,<code class="docutils literal"><span class="pre">'0s'</span></code>表示单个空字符串(而<code class="docutils literal"><span class="pre">'0c'</span></code>表示0个字符)。</span></p><p><span class="yiyi-st" id="yiyi-225">When packing a value <code class="docutils literal"><span class="pre">x</span></code> using one of the integer formats (<code class="docutils literal"><span class="pre">'b'</span></code>, <code class="docutils literal"><span class="pre">'B'</span></code>, <code class="docutils literal"><span class="pre">'h'</span></code>, <code class="docutils literal"><span class="pre">'H'</span></code>, <code class="docutils literal"><span class="pre">'i'</span></code>, <code class="docutils literal"><span class="pre">'I'</span></code>, <code class="docutils literal"><span class="pre">'l'</span></code>, <code class="docutils literal"><span class="pre">'L'</span></code>, <code class="docutils literal"><span class="pre">'q'</span></code>, <code class="docutils literal"><span class="pre">'Q'</span></code>), if <code class="docutils literal"><span class="pre">x</span></code> is outside the valid range for that format then <a class="reference internal" href="#struct.error" title="struct.error"><code class="xref py py-exc docutils literal"><span class="pre">struct.error</span></code></a> is raised.</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-226"><span class="versionmodified">在版本3.1中已更改:</span>在3.0中,某些整数格式包含超出范围值,并引发了<a class="reference internal" href="exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">DeprecationWarning</span></code></a>,而不是<a class="reference internal" href="#struct.error" title="struct.error"><code class="xref py py-exc docutils literal"><span class="pre">struct.error</span></code></a>。</span></p></div><p><span class="yiyi-st" id="yiyi-227"><code class="docutils literal"><span class="pre">'p'</span></code>格式字符编码“Pascal字符串”,表示由计数给出的存储在<em>固定字节数</em>中的短可变长度字符串。</span><span class="yiyi-st" id="yiyi-228">存储的第一个字节是字符串的长度,或255,取较小者。</span><span class="yiyi-st" id="yiyi-229">字符串的字节跟随。</span><span class="yiyi-st" id="yiyi-230">如果传递到<a class="reference internal" href="#struct.pack" title="struct.pack"><code class="xref py py-func docutils literal"><span class="pre">pack()</span></code></a>的字符串太长(长于计数减1),则只存储字符串的前导<code class="docutils literal"><span class="pre">count-1</span></code>个字节。</span><span class="yiyi-st" id="yiyi-231">如果字符串小于<code class="docutils literal"><span class="pre">count-1</span></code>,则用空字节填充,以便使用所有字节。</span><span class="yiyi-st" id="yiyi-232">请注意,对于<a class="reference internal" href="#struct.unpack" title="struct.unpack"><code class="xref py py-func docutils literal"><span class="pre">unpack()</span></code></a>,<code class="docutils literal"><span class="pre">'p'</span></code>格式字符消耗<code class="docutils literal"><span class="pre">count</span></code>字节,但返回的字符串永远不能包含超过255字节。</span></p><p><span class="yiyi-st" id="yiyi-233">对于<code class="docutils literal"><span class="pre">'?'</span></code></span><span class="yiyi-st" id="yiyi-234">格式字符,返回值为<a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>或<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a>。</span><span class="yiyi-st" id="yiyi-235">当封装时,使用参数对象的真值。</span><span class="yiyi-st" id="yiyi-236">在本地或标准布尔表示中的0或1将被打包,并且当分离时任何非零值将是<code class="docutils literal"><span class="pre">True</span></code>。</span></p></div><div class="section" id="examples"><h3><span class="yiyi-st" id="yiyi-237">7.1.2.3.</span><span class="yiyi-st" id="yiyi-238">示例</span></h3><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-239">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-240">所有示例假定本机字节顺序,大小和与大端机器的对齐。</span></p></div><p><span class="yiyi-st" id="yiyi-241">封装/解包三个整数的基本示例:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">struct</span> <span class="k">import</span> <span class="o">*</span>
|
||
<span class="gp">>>> </span><span class="n">pack</span><span class="p">(</span><span class="s1">'hhl'</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="go">b'\x00\x01\x00\x02\x00\x00\x00\x03'</span>
|
||
<span class="gp">>>> </span><span class="n">unpack</span><span class="p">(</span><span class="s1">'hhl'</span><span class="p">,</span> <span class="n">b</span><span class="s1">'</span><span class="se">\x00\x01\x00\x02\x00\x00\x00\x03</span><span class="s1">'</span><span class="p">)</span>
|
||
<span class="go">(1, 2, 3)</span>
|
||
<span class="gp">>>> </span><span class="n">calcsize</span><span class="p">(</span><span class="s1">'hhl'</span><span class="p">)</span>
|
||
<span class="go">8</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-242">解压缩的字段可以通过将它们分配给变量或将结果包装在命名的元组中来命名:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">record</span> <span class="o">=</span> <span class="n">b</span><span class="s1">'raymond </span><span class="se">\x32\x12\x08\x01\x08</span><span class="s1">'</span>
|
||
<span class="gp">>>> </span><span class="n">name</span><span class="p">,</span> <span class="n">serialnum</span><span class="p">,</span> <span class="n">school</span><span class="p">,</span> <span class="n">gradelevel</span> <span class="o">=</span> <span class="n">unpack</span><span class="p">(</span><span class="s1">'<10sHHb'</span><span class="p">,</span> <span class="n">record</span><span class="p">)</span>
|
||
|
||
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">namedtuple</span>
|
||
<span class="gp">>>> </span><span class="n">Student</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s1">'Student'</span><span class="p">,</span> <span class="s1">'name serialnum school gradelevel'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">Student</span><span class="o">.</span><span class="n">_make</span><span class="p">(</span><span class="n">unpack</span><span class="p">(</span><span class="s1">'<10sHHb'</span><span class="p">,</span> <span class="n">record</span><span class="p">))</span>
|
||
<span class="go">Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-243">格式字符的排序可能对大小有影响,因为满足对齐要求所需的填充是不同的:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">pack</span><span class="p">(</span><span class="s1">'ci'</span><span class="p">,</span> <span class="n">b</span><span class="s1">'*'</span><span class="p">,</span> <span class="mh">0x12131415</span><span class="p">)</span>
|
||
<span class="go">b'*\x00\x00\x00\x12\x13\x14\x15'</span>
|
||
<span class="gp">>>> </span><span class="n">pack</span><span class="p">(</span><span class="s1">'ic'</span><span class="p">,</span> <span class="mh">0x12131415</span><span class="p">,</span> <span class="n">b</span><span class="s1">'*'</span><span class="p">)</span>
|
||
<span class="go">b'\x12\x13\x14\x15*'</span>
|
||
<span class="gp">>>> </span><span class="n">calcsize</span><span class="p">(</span><span class="s1">'ci'</span><span class="p">)</span>
|
||
<span class="go">8</span>
|
||
<span class="gp">>>> </span><span class="n">calcsize</span><span class="p">(</span><span class="s1">'ic'</span><span class="p">)</span>
|
||
<span class="go">5</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-244">以下格式<code class="docutils literal"><span class="pre">'llh0l'</span></code>在结尾指定两个填充字节,假设长整数在4字节边界对齐:</span></p><pre><code class="language-python"><span></span><span class="gp">>>> </span><span class="n">pack</span><span class="p">(</span><span class="s1">'llh0l'</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||
<span class="go">b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'</span>
|
||
</code></pre><p><span class="yiyi-st" id="yiyi-245">这只有在原生大小和对齐有效时才起作用;标准尺寸和对齐不强制执行任何对齐。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-246">也可以看看</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-247">模块<a class="reference internal" href="array.html#module-array" title="array: Space efficient arrays of uniformly typed numeric values."><code class="xref py py-mod docutils literal"><span class="pre">array</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-248">同构数据的打包二进制存储。</span></dd><dt><span class="yiyi-st" id="yiyi-249">模块<a class="reference internal" href="xdrlib.html#module-xdrlib" title="xdrlib: Encoders and decoders for the External Data Representation (XDR)."><code class="xref py py-mod docutils literal"><span class="pre">xdrlib</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-250">XDR数据的封装和分拆。</span></dd></dl></div></div></div><div class="section" id="classes"><h2><span class="yiyi-st" id="yiyi-251">7.1.3.</span><span class="yiyi-st" id="yiyi-252">类</span></h2><p><span class="yiyi-st" id="yiyi-253"><a class="reference internal" href="#module-struct" title="struct: Interpret bytes as packed binary data."><code class="xref py py-mod docutils literal"><span class="pre">struct</span></code></a>模块还定义了以下类型:</span></p><dl class="class"><dt id="struct.Struct"><span class="yiyi-st" id="yiyi-254"><em class="property">class </em><code class="descclassname">struct.</code><code class="descname">Struct</code><span class="sig-paren">(</span><em>format</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-255">返回一个新的Struct对象,根据格式字符串<em>格式</em>写入和读取二进制数据。</span><span class="yiyi-st" id="yiyi-256">创建一个Struct对象并调用其方法比调用具有相同格式的<a class="reference internal" href="#module-struct" title="struct: Interpret bytes as packed binary data."><code class="xref py py-mod docutils literal"><span class="pre">struct</span></code></a>函数更有效,因为格式字符串只需要编译一次。</span></p><p><span class="yiyi-st" id="yiyi-257">编译的Struct对象支持以下方法和属性:</span></p><dl class="method"><dt id="struct.Struct.pack"><span class="yiyi-st" id="yiyi-258"><code class="descname">pack</code><span class="sig-paren">(</span><em>v1</em>, <em>v2</em>, <em>...</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-259">与<a class="reference internal" href="#struct.pack" title="struct.pack"><code class="xref py py-func docutils literal"><span class="pre">pack()</span></code></a>函数相同,使用编译的格式。</span><span class="yiyi-st" id="yiyi-260">(<code class="docutils literal"><span class="pre">len(result)</span></code>将等于<a class="reference internal" href="#struct.Struct.size" title="struct.Struct.size"><code class="xref py py-attr docutils literal"><span class="pre">size</span></code></a>。)</span></p></dd></dl><dl class="method"><dt id="struct.Struct.pack_into"><span class="yiyi-st" id="yiyi-261"><code class="descname">pack_into</code><span class="sig-paren">(</span><em>buffer</em>, <em>offset</em>, <em>v1</em>, <em>v2</em>, <em>...</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-262">与<a class="reference internal" href="#struct.pack_into" title="struct.pack_into"><code class="xref py py-func docutils literal"><span class="pre">pack_into()</span></code></a>函数相同,使用编译的格式。</span></p></dd></dl><dl class="method"><dt id="struct.Struct.unpack"><span class="yiyi-st" id="yiyi-263"><code class="descname">unpack</code><span class="sig-paren">(</span><em>buffer</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-264">与<a class="reference internal" href="#struct.unpack" title="struct.unpack"><code class="xref py py-func docutils literal"><span class="pre">unpack()</span></code></a>函数相同,使用编译后的格式。</span><span class="yiyi-st" id="yiyi-265">缓冲区的大小(字节)必须等于<a class="reference internal" href="#struct.Struct.size" title="struct.Struct.size"><code class="xref py py-attr docutils literal"><span class="pre">size</span></code></a>。</span></p></dd></dl><dl class="method"><dt id="struct.Struct.unpack_from"><span class="yiyi-st" id="yiyi-266"><code class="descname">unpack_from</code><span class="sig-paren">(</span><em>buffer</em>, <em>offset=0</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-267">与<a class="reference internal" href="#struct.unpack_from" title="struct.unpack_from"><code class="xref py py-func docutils literal"><span class="pre">unpack_from()</span></code></a>函数相同,使用编译的格式。</span><span class="yiyi-st" id="yiyi-268">缓冲区的大小(以字节为单位)减去<em>offset</em>,必须至少为<a class="reference internal" href="#struct.Struct.size" title="struct.Struct.size"><code class="xref py py-attr docutils literal"><span class="pre">size</span></code></a>。</span></p></dd></dl><dl class="method"><dt id="struct.Struct.iter_unpack"><span class="yiyi-st" id="yiyi-269"><code class="descname">iter_unpack</code><span class="sig-paren">(</span><em>buffer</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-270">与<a class="reference internal" href="#struct.iter_unpack" title="struct.iter_unpack"><code class="xref py py-func docutils literal"><span class="pre">iter_unpack()</span></code></a>函数相同,使用编译的格式。</span><span class="yiyi-st" id="yiyi-271">缓冲区的大小(以字节为单位)必须是<a class="reference internal" href="#struct.Struct.size" title="struct.Struct.size"><code class="xref py py-attr docutils literal"><span class="pre">size</span></code></a>的倍数。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-272"><span class="versionmodified">版本3.4中的新功能。</span></span></p></div></dd></dl><dl class="attribute"><dt id="struct.Struct.format"><span class="yiyi-st" id="yiyi-273"><code class="descname">format</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-274">用于构造此Struct对象的格式字符串。</span></p></dd></dl><dl class="attribute"><dt id="struct.Struct.size"><span class="yiyi-st" id="yiyi-275"><code class="descname">size</code> </span></dt><dd><p><span class="yiyi-st" id="yiyi-276">对应于<a class="reference internal" href="functions.html#format" title="format"><code class="xref py py-attr docutils literal"><span class="pre">format</span></code></a>的结构(以及因此由<a class="reference internal" href="#struct.pack" title="struct.pack"><code class="xref py py-meth docutils literal"><span class="pre">pack()</span></code></a>方法产生的字节对象)的计算大小。</span></p></dd></dl></dd></dl></div></div></div> |