2019-04-08 23:22:26 +08:00

1 line
6.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="body" role="main"><div class="section" id="module-copy"><h1><span class="yiyi-st" id="yiyi-10">8.10. <a class="reference internal" href="#module-copy" title="copy: Shallow and deep copy operations."><code class="xref py py-mod docutils literal"><span class="pre">copy</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/copy.py">Lib/copy.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">Python中的赋值语句不复制对象它们在目标和对象之间创建绑定。</span><span class="yiyi-st" id="yiyi-13">对于可变的或包含可变项的容器,有时需要一个副本,所以可以改变一个副本而不改变另一个。</span><span class="yiyi-st" id="yiyi-14">此模块提供通用的浅层和深层复制操作(如下所述)。</span></p><p><span class="yiyi-st" id="yiyi-15">接口概要:</span></p><dl class="function"><dt id="copy.copy"><span class="yiyi-st" id="yiyi-16"><code class="descclassname">copy.</code><code class="descname">copy</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-17">返回<em>x</em>的浅拷贝。</span></p></dd></dl><dl class="function"><dt id="copy.deepcopy"><span class="yiyi-st" id="yiyi-18"><code class="descclassname">copy.</code><code class="descname">deepcopy</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-19">返回<em>x</em>的深度副本。</span></p></dd></dl><dl class="exception"><dt id="copy.error"><span class="yiyi-st" id="yiyi-20"><em class="property">exception </em><code class="descclassname">copy.</code><code class="descname">error</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-21">引发模块特定错误。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-22">浅层和深层复制之间的区别仅与复合对象(包含其他对象,如列表或类实例的对象)有关:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-23"><em>浅拷贝</em>构建一个新的复合对象,然后(尽可能地)将原始对象中<em>引用</em>插入到新对象中。</span></li><li><span class="yiyi-st" id="yiyi-24"><em>深拷贝</em>构造一个新的复合对象,然后递归地把包含原始对象中找到的对象的<em>副本</em>插入到新对象中。</span></li></ul><p><span class="yiyi-st" id="yiyi-25">对于浅拷贝操作,深拷贝操作通常不存在两个问题:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-26">递归对象(直接或间接包含对自身引用的复合对象)可能导致递归循环。</span></li><li><span class="yiyi-st" id="yiyi-27">因为深拷贝<em>一切</em>它可能拷贝太多,例如甚至应该在拷贝之间共享的管理数据结构。</span></li></ul><p><span class="yiyi-st" id="yiyi-28"><a class="reference internal" href="#copy.deepcopy" title="copy.deepcopy"><code class="xref py py-func docutils literal"><span class="pre">deepcopy()</span></code></a>函数通过以下方式避免了这些问题:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-29">保持在当前复制过程中已经复制的对象的“备忘录”字典;和</span></li><li><span class="yiyi-st" id="yiyi-30">让用户定义的类覆盖复制操作或复制的组件集。</span></li></ul><p><span class="yiyi-st" id="yiyi-31">此模块不复制像模块,方法,堆栈跟踪,堆栈框架,文件,套接字,窗口,数组或任何类似类型的类型。</span><span class="yiyi-st" id="yiyi-32">它通过返回原始对象不变来“复制”函数和类(浅和深)这与由<a class="reference internal" href="pickle.html#module-pickle" title="pickle: Convert Python objects to streams of bytes and back."><code class="xref py py-mod docutils literal"><span class="pre">pickle</span></code></a>模块处理的方式兼容。</span></p><p><span class="yiyi-st" id="yiyi-33">可以使用<a class="reference internal" href="stdtypes.html#dict.copy" title="dict.copy"><code class="xref py py-meth docutils literal"><span class="pre">dict.copy()</span></code></a>和通过分配整个列表的片段来创建字典的浅拷贝,例如,<code class="docutils literal"><span class="pre">copied_list</span> <span class="pre">=</span> <span class="pre">original_list []</span></code></span></p><p id="index-0"><span class="yiyi-st" id="yiyi-34">类可以使用相同的接口来控制用于控制酸洗的复制。</span><span class="yiyi-st" id="yiyi-35">有关这些方法的信息,请参阅模块<a class="reference internal" href="pickle.html#module-pickle" title="pickle: Convert Python objects to streams of bytes and back."><code class="xref py py-mod docutils literal"><span class="pre">pickle</span></code></a>的描述。</span><span class="yiyi-st" id="yiyi-36">实际上,<a class="reference internal" href="#module-copy" title="copy: Shallow and deep copy operations."><code class="xref py py-mod docutils literal"><span class="pre">copy</span></code></a>模块使用来自<a class="reference internal" href="copyreg.html#module-copyreg" title="copyreg: Register pickle support functions."><code class="xref py py-mod docutils literal"><span class="pre">copyreg</span></code></a>模块的注册pickle函数。</span></p><p id="index-1"><span class="yiyi-st" id="yiyi-37">为了让一个类定义自己的拷贝实现,它可以定义特殊的方法<code class="xref py py-meth docutils literal"><span class="pre">__copy__()</span></code><code class="xref py py-meth docutils literal"><span class="pre">__deepcopy__()</span></code></span><span class="yiyi-st" id="yiyi-38">前者被称为实现浅拷贝操作;不会传递额外的参数。</span><span class="yiyi-st" id="yiyi-39">后者被称为实现深拷贝操作;它传递一个参数,备忘录字典。</span><span class="yiyi-st" id="yiyi-40">如果<code class="xref py py-meth docutils literal"><span class="pre">__deepcopy__()</span></code>实现需要创建组件的深拷贝,则应调用<a class="reference internal" href="#copy.deepcopy" title="copy.deepcopy"><code class="xref py py-func docutils literal"><span class="pre">deepcopy()</span></code></a>函数,将组件作为第一个参数,论据。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-41">也可以看看</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-42">模块<a class="reference internal" href="pickle.html#module-pickle" title="pickle: Convert Python objects to streams of bytes and back."><code class="xref py py-mod docutils literal"><span class="pre">pickle</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-43">讨论用于支持对象状态检索和恢复的特殊方法。</span></dd></dl></div></div></div>