python中有一個模塊copy,deepcopy函數用于深拷貝,copy函數用于淺拷貝。要理解淺拷貝,必須先弄清楚python中的引用。
### 引用
**Python中一切都是對象,變量中存放的是對象的引用**。這是一個普遍的法則。**可以說 Python 沒有賦值,只有引用**。如,a=1,變量a只是整數對象1的引用。
####
### 可變對象與不可變對象及其引用
#### 一、不可變對象
不可變對象包括:數字,字符串,元組。
由于Python中的變量存放的是對象引用,所以對于不可變對象而言,盡管對象本身不可變,但變量的對象引用是可變的。運用這樣的機制,有時候會讓人產生糊涂,似乎可變對象變化了。如下面的代碼:
~~~
i=73
i+=2
~~~
這里的‘=’表示引用。

從上面得知,不可變的對象的特征沒有變,依然是不可變對象,變的只是創建了新對象,改變了變量的對象引用。
#### 二、可變對象
可變對象包括:列表、字典
其對象的內容是可以變化的。當對象的內容發生變化時,變量的對象引用是不會變化的。如下面的例子。
~~~
m=[5,9]
m+=[6]
~~~
列表m的每個元素均是對象的引用。對象的生成,涉及到對應機制,如整形對象分為大整數對象和小整數對象,生成機制不同,這里不作詳細闡述。

### 三、函數的參數傳遞
函數的參數傳遞,本質上傳遞的是引用。
### 拷貝
(1)沒有限制條件的分片表達式(L[:])能夠復制序列,但此法只能淺層復制。
(2)字典 copy 方法,D.copy() 能夠復制字典,但此法只能淺層復制
(3)有些內置函數,例如 list,能夠生成拷貝 list(L)
(4)copy 標準庫模塊能夠生成完整拷貝:deepcopy,遞歸 copy
### 淺拷貝
淺拷貝由copy模塊中的copy()函數實現,簡單地說,copy.copy?淺拷貝?只拷貝父對象,不會拷貝對象的內部的可變子對象。具體點說就是,**淺拷貝是指拷貝的只是原對象元素的引用,換句話說,淺拷貝產生的對象本身是新的,但是它的內容不是新的,只是對原子對象的一個引用。**
~~~
import copy
aList=[[1,2],3,4]
bList=copy.copy(aList)
print aList
print bList
print id(aList)
print id(bList)
aList[0][0]=5
print aList
print bList
~~~
由id(aList)不等于id(bList),表明淺拷貝產生的對象本身是新的,但是它的子對象(即,那個列表)是對原子對象的一個引用。**那么3,4兩個元素呢?這就要講講python中的可變對象和不可變對象的引用了。**
但是有點需要特別提醒的,如果對象本身是不可變的,那么淺拷貝時也是引用。
見這個例子:
~~~
import copy
aList=[[1,2],3,4]
bList=copy.copy(aList)
print aList
print bList
print id(aList[1])
print id(bList[1])
aList[2]=5#變量的對象引用改變了而已
aList[0]=[0,1,1]#變量的對象引用改變了而已
print aList
print bList
~~~
總結,即**淺拷貝產生的對象本身是新的,但是它的內容不是新的,**只是對原**子對象**的一個**引用。**
### 深拷貝
淺拷貝由copy模塊中的deepcopy()函數實現,簡單地說,深拷貝?拷貝對象及其子對象。
一個例子展示引用、深拷貝與淺拷貝的不同。
~~~
import copy
aList=[[1,2],3,4]
bList=aList
cList=copy.copy(aList)
dList=copy.deepcopy(aList)
print aList
print bList
print cList
print dList
print id(aList)
print id(bList)
print id(cList)
print id(dList)
aList.append(5)
aList[0].append('hello')
print aList
print bList
print cList
print dList
~~~
其實我覺得記住這一點就行,**淺拷貝產生的對象本身是新的,但是它的內容不是新的,只是對原**子對象**的一個**引用**。關鍵是要理解python中引用的含義。**