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
>>>id(a),id(b)
>>>(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)
>>>print(L,LL)
([1, 2, 3, [‘a‘,‘b‘],4], [1, 2, 3,[‘a‘,‘b‘], 4])
>>> id(L),id(LL)
(140350607804608, 140350607804608)
三、淺復制
>>>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)
>>>print L,LL,C,CC
[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()
>>>print L,LL,C,CC
[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‘]]
由切片得到的在增加和刪除列表時,不影響其他列表,因為非嵌套層和其他列表不是同一個對象。
總結:
=號是引用對象,而列表[:]切片會產生淺復制,一個新的對象,淺復制對象中的可變類型(如列表)還是引用,深復制是所有對象類型完全復制一份,不會因某引用可變對象的修改而影響其他復制對象。
本筆記只為個人備忘總結使用,如有錯誤之處,歡迎指證,交流~
本文出自 “學地止境” 博客,請務必保留此出處http://280872.blog.51cto.com/270872/1940946
python變量及淺復制與深復制