1. 程式人生 > >python變量及淺復制與深復制

python變量及淺復制與深復制

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變量及淺復制與深復制