在python中,給一個對象賦值,實際上就是對象對內存空間存儲的值的引用。當我們把對象賦值給另一個變量的時候,這個變量并沒有拷貝這個對象,而只是拷貝了這個對象的引用而已。
一般情況下我們會通過三種方法來實現拷貝對象的引用。
直接賦值,默認淺拷貝傳遞對象的引用而已,原始列表改變,被賦值的變量也會做相同的改變。其實就是對‘對象'的引用
示例:
>>> list_demo = [2, 4, 6]>>> a = list_demo>>> print(a)[2, 4, 6]>>> id(list_demo)65006808>>> id(a)65006808>>> list_demo.append(8)>>> print(list_demo)[2, 4, 6, 8]>>> print(a)[2, 4, 6, 8]>>> id(list_demo)65006808>>> id(a)65006808>>>
通過 id() 函數我們可以得出,變量 list_demo 與 a 指向的都是同一個內存空間地址,當被賦值的 list_demo改變,被賦值的 a 同樣會做相同的改變。這種現象普遍存在于 Python 之中,這種賦值的方式實現了 “假裝” 拷貝,真實的情況還是兩個變量和同一個對象之間的引用關系。
import copy 模塊的 copy.copy() 方法,該方法只拷貝父對象,沒有拷貝子對象。且淺拷貝是創建一塊新的內存空間,但是內存空間內的元素的地址均是父對象元素的地址的拷貝。所以當父對象內部的子對象發生改變時,拷貝對象的內部的子對象也會跟著改變。
示例:
>>> list_demo1 = [2, 4, 6, [8, 10]]>>> a = list_demo1>>> print(list_demo1)[2, 4, 6, [8, 10]]>>> print(a)[2, 4, 6, [8, 10]]>>>>>>>>> import copy>>> b = copy.copy(list_demo1)>>> id(list_demo1)65103472>>> id(b)6011200>>> list_demo1.append(12)>>> print(list_demo1)[2, 4, 6, [8, 10], 12]>>> list_demo1[3][8, 10]>>>>>>>>>>>> list_demo1[3].append('hello')>>> print(list_demo1)[2, 4, 6, [8, 10, 'hello'], 12]>>> print(b)[2, 4, 6, [8, 10, 'hello']]>>> list_demo1[3][8, 10, 'hello']>>> b[3][8, 10, 'hello']>>>>>>>>>>>> id(list_demo1)65103472>>> id(b)6011200>>> id(list_demo1[3])64679128>>> id(b[3])64679128>>>
從上述代碼可以看出,在執行淺拷貝的時候,淺拷貝實際上只拷貝引用,不拷貝內容。同時,淺拷貝會針對父對象的子對象進行判斷,當父對象的子對象發生改變時,拷貝對象內的子對象同時也跟著改變。
import copy 模塊的 copy.deepcopy() 方法,深拷貝與淺拷貝相反,就是徹徹底底的拷貝,完全的拷貝了父對象及子對象,同時指向一個新的內存空間地址。此時,雖然源對象與拷貝對象的內容是一樣的,但是不管針對誰進行改動,另一個是絲毫不會受到影響的。
新聞熱點
疑難解答