天天看點

python變量及淺複制與深複制

一、變量及定義:

     變量定義:一段存放在記憶體特定區域的空間,在python中變量名沒有類型,引用的對象有類型之分;

     命名規則:字母或下劃線開頭,不能以數字開頭。

     特殊變量:以單下劃線(_)開頭的變量 不能被 from xxx import * 導入;即保護類型隻能允許其本身與子類進行通路。若内部變量标示,如: 當使用“from M import”時,不會将以一個下劃線開頭的對象引入 。以雙下劃線(__) __xx 雙下劃線的表示的是私有類型的變量。隻能允許這個類本身進行通路了,連子類也不可以用于命名一個類屬性(類變量),調用時名字被改變(在類FooBar内部,__boo變成_FooBar__boo,如self._FooBar__boo)以__xx__以雙下劃線開頭并以雙下劃線結尾的是特殊意義方法:如__init__ 使用者控制的命名空間内的變量或是屬性。

二、變量指派

    1、= 是指派對(簡單不可變類型,如資料,字元串)引用:

>>> a = 3

>>>b = a

>>>id(a),id(b)

>>>(11628840, 11628840)

> a = 13 ;b = 13

>>>(11628600, 11628600)

>>>aa = "hello world"

>>>bb= aa[:]

>>>id(aa),id(bb)

(139664106641856, 139664106641856)

>>>cc = aa[6:]

>>>id(aa),id(bb),id(cc)

(139664106641856, 139664106641856, 139664106641952)

    2、= 對可變類型引用:

>>>L = [1,2,3,['a','b']]

>>>LL = L

>>>print(L,LL)

 ([1, 2, 3,['a','b']], [1, 2, 3,['a','b']])

>>> id(L),id(LL)

(140350607804608, 140350607804608)

>>>LL.append(4)

([1, 2, 3, ['a','b'],4], [1, 2, 3,['a','b'], 4])

三、淺複制

>>>C = L[:]     

>>>id(C),id(LL),id(L)

(140350607767456, 140350607804608, 140350607804608)

>>>C[3].append('c')

>>>print L,LL,C

[1, 2, 3, ['a', 'b', 'c']] [1, 2, 3, ['a', 'b', 'c']] [1, 2, 3, ['a', 'b', 'c']]

由此可知:但使用指派引用對象類型時,是對對象的引用;切片時[:] 引用對象,其他切片産生新對象; 如果對象内嵌了可變類型對象,如清單嵌套清單對象,切片時,嵌套可變對象,依然引用自同一個對象;對于 這種就叫淺複制,不能複制内嵌對象還是引用;

四、深複制:

對原有對象的拷貝,修改原對象,不會改變複制後的對象;

>>>import copy

CC =copy.deepcopy(L)

>>>print L,LL,C,CC

[1, 2, 3, ['a', 'b', 'c']] [1, 2, 3, ['a', 'b', 'c']] [1, 2, 3, ['a', 'b', 'c']] [1, 2, 3, ['a', 'b', 'c']]

>>>id(L),id(LL),id(C),id(CC)

(139664099629320, 139664099629320, 139664099630184, 139664122961792)

>>>L.apend(4)

[1, 2, 3, ['a', 'b', 'c'], 4] [1, 2, 3, ['a', 'b', 'c'], 4] [1, 2, 3, ['a', 'b', 'c']] [1, 2, 3, ['a', 'b', 'c']]

這裡修改了L清單,L,LL随着修改,但切片得到的C沒有修改,深複制CC也沒有修改

>>>L[3].pop()

[1, 2, 3, ['a', 'b'], 4] [1, 2, 3, ['a', 'b'], 4] [1, 2, 3, ['a', 'b']] [1, 2, 3, ['a', 'b', 'c']]

這裡L,LL,C中的嵌套可變類型清單,受到了影響,但深複制得到的CC沒有受到影響,因為他完全獨立(深複制)了

 >C.append('san')

> print L,LL,C,CC

[1, 2, 3, ['a', 'b'], 4] [1, 2, 3, ['a', 'b'], 4] [1, 2, 3, ['a', 'b'], 'san'] [1, 2, 3, ['a', 'b', 'c']]

由切片得到的在增加和删除清單時,不影響其他清單,因為非嵌套層和其他清單不是同一個對象。

總結:

         =号是引用對象,而清單[:]切片會産生淺複制,一個新的對象,淺複制對象中的可變類型(如清單)還是引用,深複制是所有對象類型完全複制一份,不會因某引用可變對象的修改而影響其他複制對象。

本筆記隻為個人備忘總結使用,如有錯誤之處,歡迎指證,交流~

本文轉自 dyc2005 51CTO部落格,原文連結:http://blog.51cto.com/dyc2005/1940946,如需轉載請自行聯系原作者