Python賦值操作或函數參數傳遞,傳遞的永遠是對象引用(即內存地址),而不是對象內容。在Python中一切皆對象,對象又分為可變(mutable)和不可變(immutable)兩種類型。對象拷貝是指在內存中創建新的對象,產生新的內存地址。當頂層對象和它的子元素對象全都是immutable不可變對象時,不存在被拷貝,因為沒有產生新對象。淺拷貝(Shallow Copy),拷貝頂層對象,但不會拷貝內部的子元素對象。深拷貝(Deep Copy),遞歸拷貝頂層對象,以及它內部的子元素對象。

專業領域包括成都網站建設、做網站、成都做商城網站、微信營銷、系統平臺開發, 與其他網站設計及系統開發公司不同,成都創新互聯的整合解決方案結合了幫做網絡品牌建設經驗和互聯網整合營銷的理念,并將策略和執行緊密結合,為客戶提供全網互聯網整合方案。
Python中一切皆對象,對象就像一個塑料盒子, 里面裝的是數據。對象有不同類型,例如布爾型和整型,類型決定了可以對它進行的操作。現實生活中的"陶器"會暗含一些信息(例如它可能很重且易碎,注意不要掉到地上)。
對象的類型還決定了它裝著的數據是允許被修改的變量(可變的mutable)還是不可被修改的常量(不可變的immutable)。你可以把不可變對象想象成一個透明但封閉的盒子:你可以看到里面裝的數據,但是無法改變它。類似地,可變對象就像一個開著口的盒子,你不僅可以看到里面的數據,還可以拿出來修改它,但你無法改變這個盒子本身,即你無法改變對象的類型。
對象拷貝是指在內存中創建新的對象,產生新的內存地址。
淺拷貝(Shallow Copy),拷貝頂層對象,但不會拷貝內部的子元素對象。
2.1.1. 頂層是mutable,子元素全是immutable
當頂層對象是mutable可變對象,但是它的子元素對象全都是immutable不可變對象時,如[1, 'world', 2]
① 創建列表對象并賦值給變量a
② 導入copy模塊,使用copy.copy()函數淺拷貝a,并賦值給變量b
③ 修改變量a的子元素a[0] = 3,由于整數是不可變對象,所以并不是修改1變為3,而是更改a[0]指向對象3
當頂層對象是 mutable可變對象 ,但子元素也存在 mutable可變對象 時,如 [1, 2, ['hello','world']]
① 淺拷貝 copy.copy() 只拷貝了頂層對象,沒有拷貝子元素對象['hello','world'],即a[2]和b[2]指向同一個列表對象
② 修改a[2][1] = 'china',則b[2][1] = 'china'
當頂層對象是immutable不可變對象,同時它的子元素對象也全都是immutable不可變對象時,如(1, 2, 3)
變量a與變量b指向的是同一個元組對象,沒有拷貝
當頂層對象是immutable不可變對象時,但子元素存在mutable可變對象時,如(1, 2, ['hello','world'])
變量a與變量b指向的是相同的元組對象,并且a[2]與b[2]指向同一個列表,所以修改a[2][1]會影響b[2][1]
深拷貝(Deep Copy),遞歸拷貝頂層對象,以及它內部的子元素對象
當頂層對象是mutable可變對象,但是它的子元素對象全都是immutable不可變對象時,如[1, 'world', 2]
變量a與變量b指向不同的列表對象,修改a[0]只是將列表a的第一個元素重新指向新對象,不會影響b[0]
當頂層對象是mutable可變對象,但子元素也存在mutable可變對象時,如[1, 2, ['hello','world']]
深拷貝既拷貝了頂層對象,又遞歸拷貝了子元素對象,所以a[2]與b[2]指向了兩個不同的列表對象(但是列表對象的子元素初始指定的字符串對象一樣),修改a[2][1] = 'china'后,它重新指向了新的字符串對象(內存地址為140531581905808),不會影響到b[2][1]
當頂層對象是immutable不可變對象,同時它的子元素對象也全都是immutable不可變對象時,如(1, 2, 3)
變量a與變量b指向的是同一個元組對象,不存在拷貝
當頂層對象是immutable不可變對象時,但子元素存在mutable可變對象時,如(1, 2, ['hello','world'])
變量a與變量b指向的是不同的元組對象,同時a[2]與b[2]指向不同的列表對象,所以修改a[2][1]不會影響b[2][1]
使用=是賦值,即將列表對象的引用也賦值給變量b,可以將列表對象想像成一個盒子,變量a相當于這個盒子上的標簽,執行b = a后,相當于再在這個盒子上貼上b標簽,a和b實際上指向的是同一個對象。因此,無論我們是通過a還是通過b來修改列表的內容,其結果都會作用于雙方。
b/c/d都是a的復制,它們都指向了不同的列表對象,但是沒有拷貝子元素,a[2]和b[2]/c[2]/d[2]指向同一個列表, 相當于淺拷貝的效果
使用分片[:]操作,a和b其實是指向同一個元組,而且沒有拷貝子元素,a[2]和b[2]也指向同一個列表,相當于淺拷貝的效果
同列表類似,可以使用字典的copy()函數或者轉換函數dict()
變量a與變量b/c指向不同的字典,但是沒有拷貝子元素,a['jobs']和b['jobs']/c['jobs']指定同一個列表, 相當于淺拷貝的效果
同列表類似,可以使用集合的copy()函數或者轉換函數set()
變量a與變量b/c指向不同的集合,而集合的元素必須是hashable,所以修改集合a不會影響到b/c
淺拷貝是對一個對象父級(外層)的拷貝,并不會拷貝子級(內部),而深拷貝對一個對象是所有層次的拷貝(遞歸),內部和外部都會被拷貝過來。
使用淺拷貝的時候,分為兩種情況。
第一種,如果最外層的數據類型是可變的,比如說列表,字典等,淺拷貝會開啟新的地址空間去存放。
第二種,如果最外層的數據類型是不可變的,比如元組,字符串等,淺拷貝對象的時候,還是引用對象的地址空間。
深拷貝也分兩種情況:
第一種,最外層數據類型可變。這個時候,內部和外部的都會拷貝過來。
第二種,外層數據類型不可變,如果里面是可變數據類型,會新開辟地址空間存放。如果內部數據類型不可變,才會如同淺拷貝一樣,是對地址的引用。
賦值(=),就是創建了對象的一個新的引用,修改其中任意一個變量都會影響到另一個。
淺拷貝:創建一個新的對象,但它包含的是對原始對象中包含項的引用(如果用引用的方式修改其中一個對象,另外一個也會修改改變){1,完全切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}
深拷貝:創建一個新的對象,并且遞歸的復制它所包含的對象(修改其中一個,另外一個不會改變){copy模塊的deep.deepcopy()函數}
在Python中對象的賦值(=)其實就是對象的引用。即:當創建一個對象,把它賦值給另一個變量時,python并沒有拷貝這個對象,只是拷貝了這個對象的引用而已。
Python中對象的拷貝分為:淺拷貝(copy)和深拷貝(deepcopy)。
淺拷貝:拷貝了最外圍的對象本身,內部的元素都只是拷貝了一個引用而已。也就是,將原對象在內存中引用地址拷貝過來,然后讓新的對象指向這個地址。可以使用“=”或列表自帶的copy()函數(如list.copy()),或使用copy模塊的copy()函數。
深拷貝:外圍和內部元素都進行了拷貝對象本身,而不是引用。即把對象復制一遍,并且該對象中引用的其他對象也同時復制,完全得到一個新的一模一樣的對象,對新對象里的值進行修改不會影響原有對象,新對象和原對象完全分離開。深拷貝只能使用copy模塊中deepcopy()函數,使用前要導入:from copy import deepcopy。
Python中對象分為不可變對象 、可變對象。
不可變對象:一旦創建就不可修改的對象,例如:字符串、元組、數字
可變對象:可以修改的對象,例如:列表、字典。
其中Python中的切片可以應用于:列表、元組、字符串,但不能應用于字典。
而深淺拷貝,可應用于序列(列表、元組、字符串),也可應用于字典。
其中不可變對象,不管是深拷貝還是淺拷貝,地址值在拷貝后的值都是一樣的。
以下以元組(不可變類型)為例
從上述示例可以看出:
不可變對象類型,沒有被拷貝的說法,即便是用深拷貝,查看id的話也是一樣的,如果對其重新賦值,也只是新創建一個對象,替換掉舊的而已。
所以不可變類型,不管是深拷貝還是淺拷貝,地址值和拷貝后的值都是一樣的。
以下以列表(可變類型)為例
第一種方法:使用=號淺拷貝
輸出結果:
第二種方法:使用copy淺拷貝
輸出結果:
第三種方法:使用deepcopy深拷貝
輸出結果:
從上述示例可以看出:
=淺拷貝:值相等,地址相等
copy淺拷貝:值相等,地址不相等
deepcopy深拷貝:值相等,地址不相等
總結:
1,深淺拷貝都是對源對象的復制,占用不同的內存空間。
2,不可變類型的對象,對于深淺拷貝毫無影響,最終的地址值和值都是相等的。
3,可變類型的對象,使用=淺拷貝時, 值相等,地址相等,對新對象里的值進行修改同時會影響原有對象;使用copy淺拷貝時值相等,地址不相等;使用deepcopy深拷貝時值相等,地址不相等。可以看出針對可變類型copy淺拷貝和deepcopy深拷貝,對新對象里的值進行修改不會影響原有對象。
網站名稱:python深拷貝函數 python淺拷貝與深拷貝
分享地址:http://www.yijiale78.com/article34/hhiipe.html
成都網站建設公司_創新互聯,為您提供、全網營銷推廣、做網站、服務器托管、手機網站建設、網頁設計公司
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯