pythonでの浅いコピーと深いコピー

2185 ワード

この2,3日振り返ってpythonの賦値、浅いコピーと深いコピーを見て、以前見たときはいつも彼らの間に関係があると思っていましたが、はっきりしていませんでした.今日はやっと手がかりがあったので、私の理解を共有します.
まず、pythonの付与値は、次のような参照を付与します.
foo1=1.0
foo2=foo1
オペレータisで判断すると、pythonが最初にオブジェクト1.0を作成し、そのオブジェクトの参照がfoo 1とfoo 2に割り当てられたため、結果はtrueであることがわかります.
foo1=1.0
foo2=1.0
このとき、これは実は2つの異なるオブジェクトを作成し、内蔵関数id()で両者のアイデンティティが異なることを発見することができます.
pythonにはもう一つの特例があります.例えば、
a=1
b=1
id(a)=id(b)が見つかります.pythonはこれらの小さな整数がよく使われると考えているので、pythonは一部の小さな整数をキャッシュします.
次に浅いコピーと深いコピーについて話します.
シーケンスタイプは3つの方法で浅いコピーを実現することができ、浅いコピーもデフォルトのコピータイプである:(1)完全スライス操作;(2)list()などのファクトリ関数を利用する;(3)copyモジュールのcopy()関数を使用します.ただし、非コンテナタイプについてはコピーされていません.「pythonコアプログラミング」という本では、「1つのオブジェクトを浅いコピーするのは、元のオブジェクトと同じタイプが新しく作成されました.その内容は元のオブジェクト要素の参照です.言い換えれば、このコピーのオブジェクト自体は新しいですが、その内容はそうではありません.」この文を読み終わったら、浅いコピーは実際には付与されていますが、後でそうではないことに気づきました.付与された結果は彼らのアイデンティティが同じなので、しかし、浅いコピーの身分は違います.次に、本の例と私の考えを結びつけて、この言葉がどういう意味なのかを説明します.
fanwei@ubuntu:~$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> person=['name',['saveing',100]]
>>> wife=person[:]
>>> hubb=list(person)
>>> id(person)
3078619916L
>>> id(wife)
3078621548L
>>> id(hubb)
3078621996L

コードの結果からhubbとwifeはpersonの浅いコピーの結果ですが、彼らの身分は違います.彼らの内容を見てみましょう.
>>>[id(x) for x in hubby]
[3078622112L,3078534412L]
>>>[id(x) for x in wife]
[3078622112L,3078534412L]

両者の内容の身分は同じだ.この点から,「コピーオブジェクト自体が新しい」ということは,以前コード検証のperson,hubb,wifeのアイデンティティが異なり,「コンテンツが古い」ということは,我々が検証したばかりであるため,コンテンツの浅いコピーは「付与」と見なすことができる.「hubbの「100」を「50」に変更すると、wifeの「100」も「50」になります.これは、コンテンツの浅いコピーが「付与」であることを示しています.つまり、2つの参照が同じオブジェクトを指し、変更後の2つのアイデンティティが同じであることを示しています.また、hubb[0]、wife[0]文字列なので、コピーしていないので、新しいタイプを作成したので、両者の「name」を改名すると、彼らの身分が違います.深いコピーについては、オブジェクトとコンテンツのアイデンティティが異なることは言うまでもありません.今、「対象自体が新しい、内容が古い」という言葉の本当の意味がわかるでしょう.
参考資料:
http://www.cnblogs.com/wait123/archive/2011/10/10/2206580.html
http://www.01happy.com/python-shallow-copy-and-deep-copy/