이 문서의 예제에서는 Python 할당 및 복사를 이해하는 방법을 설명합니다. 참조를 위해 모든 사람과 공유하세요. 세부 사항은 다음과 같습니다.
Python에서는 모든 것이 객체이며, 객체는 "변수 이름"을 통해 참조됩니다. 변수 이름"은 "이름"입니다. 우리 각자가 자신의 이름을 가지고 있는 것처럼 사람을 이름으로 참조하고, 코드에서 개체를 이름으로 참조합니다.
변수 할당은 개체에 이름을 바인딩하는 것입니다. 할당은 개체를 복사하지 않습니다. 우리가 태어날 때 부모님이 이름을 지어주듯이 누군가에게 별명을 지어준다고 해서 사람이 늘어나는 것이 아니라 이름이 늘어나는 것뿐입니다.
두 개체를 비교하는 두 가지 방법이 있습니다. 즉, is와 ==, 는
무엇입니까? 비교되는 것은 두 개체가 동일한지 여부입니다. 동일한 개체인지 여부는 개체의 ID 값인 ==
비교되는 것은 두 개체의 값이 같은지 여부입니다is
比较的是两个对象是否相同,通过对象的ID值可识别是否为相同对象,==
比较的是两个对象的值是否相等
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x1 = [<span class="hljs-number" style="color:rgb(0,128,128);">1</span>,<span class="hljs-number" style="color:rgb(0,128,128);">2</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x2 = [<span class="hljs-number" style="color:rgb(0,128,128);">1</span>,<span class="hljs-number" style="color:rgb(0,128,128);">2</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x1 <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> x2<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">False</span><br><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>id(x1)<br><span class="hljs-number" style="color:rgb(0,128,128);">4338854088</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>id(x2)<br><span class="hljs-number" style="color:rgb(0,128,128);">4338904392</span><br><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x1 == x2<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">True</span></code>
x1 和 x2 的值虽然相同,但在内存中是两个独立的不同的对象,占据不同的内存空间,就好比两个长得一样的苹果摆在桌子上,实则为两个不同的物体。
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x3 = x2<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x3 <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> x2<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">True</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>id(x3)<br><span class="hljs-number" style="color:rgb(0,128,128);">4338904392</span></code>
前面说了,赋值是给对象绑定名字,这里我们只不过是给 x2 对应的那个对象绑定了一个新的名字叫 x3,这就好比桌上放了一个苹果,开始给它贴了一个 x2 的标签,后来又给它添了一个 x3 的标签,本质上还是同一个苹果,所以,x2 和 x3 所指的其实是同一个对象。
通过x2 修改对象时,x3 也会跟着变化,因为本质上它们是同一个对象,这就好比张三和小张是同一个人时,给张三添衣服其实就是给小张添衣服。
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x2.append(<span class="hljs-number" style="color:rgb(0,128,128);">3</span>)<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x2<br>[<span class="hljs-number" style="color:rgb(0,128,128);">1</span>, <span class="hljs-number" style="color:rgb(0,128,128);">2</span>, <span class="hljs-number" style="color:rgb(0,128,128);">3</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x3<br>[<span class="hljs-number" style="color:rgb(0,128,128);">1</span>, <span class="hljs-number" style="color:rgb(0,128,128);">2</span>, <span class="hljs-number" style="color:rgb(0,128,128);">3</span>]</code>
但是,当我给 x2 重新赋值时,相当于 x2 不再引用之前的对象,而引用新对象, x3 依然引用之前的对象。好比桌上一大苹果开始贴了 x2 和 x3 两个标签,给 x2 重新赋值就相当于把 x2 标签贴到另外一个苹果,但是 x3 还是贴在老苹果身上。
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x2 = [<span class="hljs-number" style="color:rgb(0,128,128);">3</span>, <span class="hljs-number" style="color:rgb(0,128,128);">4</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x3<br>[<span class="hljs-number" style="color:rgb(0,128,128);">1</span>, <span class="hljs-number" style="color:rgb(0,128,128);">2</span>, <span class="hljs-number" style="color:rgb(0,128,128);">3</span>]</code>
在业务中有时我们需要复制一个对象,但是又不想对原对象产生副作用,肯定不能通过赋值给一个新变量来解决(因为赋值不是拷贝对象),所以 Python 专门提供了一种拷贝机制,基于原对象快速创建出一个含有相同值的对象。该功能由 copy
>>> s = [1,2,3] >>> sc = copy.copy(s) # 浅拷贝 >>> sc [1, 2, 3]
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>sdc = copy.deepcopy(s) <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic;"># 深拷贝</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>sdc<br>[<span class="hljs-number" style="color:rgb(0,128,128);">1</span>, <span class="hljs-number" style="color:rgb(0,128,128);">2</span>, <span class="hljs-number" style="color:rgb(0,128,128);">3</span>]</code>
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>s == sc == sdc <br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">True</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>s <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> sc <br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">False</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>s <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> sdc<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">False</span></code>
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x = [<span class="hljs-number" style="color:rgb(0,128,128);">2</span>, <span class="hljs-number" style="color:rgb(0,128,128);">3</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>y = [<span class="hljs-number" style="color:rgb(0,128,128);">7</span>, <span class="hljs-number" style="color:rgb(0,128,128);">11</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>z = [x, y]<br><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>a = copy.copy(z) <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic;"># 浅拷贝</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>a[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>] <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> z[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>]<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">True</span></code>
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);text-align:justify;"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>b = copy.deepcopy(z) <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic;"># 深拷贝</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>b[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>] <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> z[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>]<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">False</span></code>
两者的区别在于拷贝组合对象,比如列表中还有列表,字典中还有字典或者列表的情况时,浅拷贝只拷贝了外面的壳子,里面的元素并没有拷贝,而深拷贝则是把壳子和里面的元素都拷贝了一份新的。
来看一个例子:
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>x = [<span class="hljs-number" style="color:rgb(0,128,128);">2</span>, <span class="hljs-number" style="color:rgb(0,128,128);">3</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>y = [<span class="hljs-number" style="color:rgb(0,128,128);">7</span>, <span class="hljs-number" style="color:rgb(0,128,128);">11</span>]<br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>z = [x, y]<br><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>a = copy.copy(z) <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic;"># 浅拷贝</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>a[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>] <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> z[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>]<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">True</span></code>
拷贝出来的对象 a 中的元素引用的是 x 和 y,当你修改 x 的值,a 也会跟着变。
<code class="hljs language-python" style="font-size:.85em;font-family:Consolas, Inconsolata, Courier, monospace;margin:0px .15em;white-space:pre;border-width:1px;border-style:solid;border-color:rgb(204,204,204);padding:.5em;color:rgb(51,51,51);background:rgb(248,248,248);text-align:justify;"><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>b = copy.deepcopy(z) <span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic;"># 深拷贝</span><br><span class="hljs-prompt" style="color:rgb(153,0,115);">>>> </span>b[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>] <span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">is</span> z[<span class="hljs-number" style="color:rgb(0,128,128);">0</span>]<br><span class="hljs-keyword" style="color:rgb(51,51,51);font-weight:bold;">False</span></code>
对于深拷贝,里面的元素也重新拷贝了一份,拷贝了一份与x和y等值的两个元素,修改 x 和 y 的值,不会对 b 产生影响
对列表的切片拷贝 z[:]
或者是调用对象的copy方法 list.copy()
都属于浅拷贝。对于自定义对象,我们还可以自己实现 __copy__
方法和 __deepcopy__
方法
相关阅读:
Django入门实践指南-第1部分
厉害了,10行代码实现抽奖助手自动参与抽奖
看了很多代码,却依然无从下手?
위 내용은 Python 할당 및 복사 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!