淺析Python中的賦值和深淺拷貝
python中,A object = B object 是一種賦值操作,賦的值不是一個(gè)對象在內(nèi)存中的空間,而只是這個(gè)對象在內(nèi)存中的位置 。
此時(shí)當(dāng)B對象里面的內(nèi)容發(fā)生更改的時(shí)候,A對象也自然而然的會(huì)跟著更改。
name = ["root","admin"] cp_name = name # 對cp_name進(jìn)行賦值操作 # 對name列表進(jìn)行插入 name.append('root_temp') print(name,cp_name) # ['root', 'admin', 'root_temp'] ['root', 'admin', 'root_temp'] print(id(name),id(cp_name)) # 23991960 23991960
而想要進(jìn)行淺拷貝或者深拷貝,就需要引入copy模塊 。
首先來說下淺拷貝,當(dāng)進(jìn)行淺拷貝時(shí),使用copy.copy()方法。
import copy name = ["root","admin"] # 進(jìn)行淺拷貝操作 cp_name = copy.copy(name) # 查看cp_name,name print(name,cp_name) # ['root', 'admin'] ['root', 'admin'] 拷貝成功 #查看地址 print(id(name),id(cp_name)) # 21146920 21147160 內(nèi)存地址并不相同 # 嘗試對name進(jìn)行更改 name.append('root_temp') # 查看cp_name是否更改 print(cp_name) # ['root', 'admin'] 內(nèi)容并沒有更改
A = copy.copy(B) 此時(shí)A對象相當(dāng)于把B對象中的內(nèi)容給完成的拷貝了一份,存儲(chǔ)在了一份新的內(nèi)存地址當(dāng)中。
其中有一點(diǎn)需要注意,如下:
import copy name = ['root','admin',['root_temp','admin_temp']] cp_name = copy.copy(name) # 查看兩個(gè)對象的地址 print(id(name),id(cp_name)) # 24358504 24428952 二者的地址并不相同 # 對name 進(jìn)行更改 name.append('test') # 查看cp_name是否更改 print(cp_name) # ['root', 'admin', ['root_temp', 'admin_temp']] cp_name并未更改 # 在來對name中的列表對象進(jìn)行更改 name[2].append('ttttt') print(cp_name) # ['root', 'admin', ['root_temp', 'admin_temp', 'ttttt']] 發(fā)現(xiàn)cp_name內(nèi)容發(fā)生了變化
在上面的代碼中,通過copy.copy()方法把name對象淺拷貝給了cp_name,此時(shí)二者的內(nèi)容相同,但是地址不同,說明通過淺拷貝后,cp_name相當(dāng)于重新開辟了一塊內(nèi)存空間用來存儲(chǔ)拷貝過來的內(nèi)容。所以說,當(dāng)name.append()第一次插入值的時(shí)候,cp_name對象沒有變化,因?yàn)閏p_name和name 處于兩個(gè)不同的內(nèi)存空間,是獨(dú)立的。
而淺拷貝的問題在于,只能夠拷貝第一層的內(nèi)容,至于說第二層以及第三層或者第n層,對于淺拷貝來說都是無能為力的,只能簡單的拷貝一份內(nèi)存地址。
所以說,對于name 這個(gè)對象中,列表第一層發(fā)生更改,是不會(huì)影響cp_name的,而一旦更改了第二層或者第n層的內(nèi)容,cp_name都會(huì)被影響,因?yàn)榇藭r(shí)的cp_name對象里面子列表是與name的子列表共享相同的內(nèi)存空間。
而如果想要對第一層以及第二層甚至第n層都進(jìn)行徹底的拷貝,那么就需要使用深層拷貝。
深層拷貝需要使用copy模塊的deepcopy()方法。
import copy name = ['root','admin',['root_temp','admin_temp']] cp_name = copy.deepcopy(name) # 查看二者的id print(id(name),id(cp_name)) # 29863528 29933976 地址不同,說明開辟了處于兩塊不同的空間 # 對name 第一層以及第二層進(jìn)行更改 name.append('t1') name[2].append('t2') # 查看cp_name是否內(nèi)容發(fā)生變化 print(cp_name) # ['root', 'admin', ['root_temp', 'admin_temp']] 內(nèi)容并未發(fā)生更改
此時(shí),cp_name對象并不會(huì)被name所影響,無論name對象的第一層列表還是第n層的更改和變化,都不會(huì)影響cp_name,因?yàn)榇藭r(shí)通過深層拷貝,兩個(gè)對象已經(jīng)完全的處于兩個(gè)不同的獨(dú)立內(nèi)存空間,而這也就是深層拷貝。
總結(jié)
以上所述是小編給大家介紹的Python中的賦值和深淺拷貝,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
python tkinter制作用戶登錄界面的簡單實(shí)現(xiàn)
這篇文章主要介紹了python tkinter制作用戶登錄界面的簡單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Python基于遞歸算法實(shí)現(xiàn)的走迷宮問題
這篇文章主要介紹了Python基于遞歸算法實(shí)現(xiàn)的走迷宮問題,結(jié)合迷宮問題簡單分析了Python遞歸算法的定義與使用技巧,需要的朋友可以參考下2017-08-08詳解Python模塊化--模塊(Modules)和包(Packages)
這篇文章主要介紹了使用Python的模塊(Modules)和包(Packages),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08利用Tensorflow構(gòu)建和訓(xùn)練自己的CNN來做簡單的驗(yàn)證碼識別方式
今天小編就為大家分享一篇利用Tensorflow構(gòu)建和訓(xùn)練自己的CNN來做簡單的驗(yàn)證碼識別方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01Python使用asyncio包處理并發(fā)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Python使用asyncio包處理并發(fā),asyncio包使用事件循環(huán)驅(qū)動(dòng)的協(xié)程實(shí)現(xiàn)并發(fā),本文通過實(shí)例代碼給大家介紹的非常詳細(xì)對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12Python實(shí)現(xiàn)的多叉樹尋找最短路徑算法示例
這篇文章主要介紹了Python實(shí)現(xiàn)的多叉樹尋找最短路徑算法,結(jié)合實(shí)例形式分析了Python使用深度優(yōu)先查找獲取多叉樹最短路徑相關(guān)操作技巧,需要的朋友可以參考下2018-07-07Python實(shí)現(xiàn)繪制雙柱狀圖并顯示數(shù)值功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)繪制雙柱狀圖并顯示數(shù)值功能,涉及Python數(shù)值運(yùn)算及基于matplotlib的圖形繪制相關(guān)操作技巧,需要的朋友可以參考下2018-06-06