python中浅拷贝与深拷贝
參考鏈接
1. 引用 https://blog.csdn.net/qq_38556217/article/details/103002827
2. Python中變量在內存的存儲與地址變化詳解(深淺拷貝,值/引用傳遞、可變不可變數據類型)
3. python深拷貝和淺拷貝的區別
首先深拷貝和淺拷貝都是對象的拷貝,都會生成一個看起來相同的對象,他們本質的區別是拷貝出來的對象的地址是否和原對象一樣,也就是地址的復制還是值的復制的區別
一、可變對象與不可變對象
3.id()獲取對象的內存地址
-5到256的整數、True和False、由字母、數字、下滑線組成的字符串
二、對可變對此的操作是否新建對象?
這里以列表為例,實驗對列表的操作,是否改變了列表對象,及id(列表對象)是否發生了變化。
2.1 不改變id(列表對象)的操作
- append()方法
- += 連接列表
- 刪除某個元素 del l[1]
- 改變某個元素的值 l[2]=10
2.2 改變id(列表對象)的操作
* 切片操作,`a[:2]`,及全部復制`a[:]` * 連接列表 `a = a + [...]`三、賦值、淺拷貝與深拷貝
Python 中賦值語句不復制對象,而是在目標和對象之間創建綁定 (bindings) 關系。
3.1 賦值操作=
相當于復制一個引用,指向同一個內存地址。改變其中一個變量的值,
- 如果是可變對象,其余的也會跟著變。它們之間的id值相同。
- 如果是不可變對象,改變其中一個變量的值相當于新建一個對象,它們之間的id值不同。
3.2 淺拷貝
淺拷貝會新建一個對象,拷貝對象與元對象的變化間有無關聯,要看元對象中的元素類型
- 不包含。拷貝后對象變化與原對象間沒有關系
- 包含。可變對象的變化會同時發生在原對象和拷貝對象中。
拷貝的對象中,包含可變對象時,新對象中保存的是可變對象的地址。
3.3 深拷貝
拷貝后,拷貝后對象變化與原對象間沒有關系
淺拷貝與深拷貝的區別,總的來說就是拷貝一層和多層的區別
深拷貝操作通常存在兩個問題, 而淺拷貝操作并不存在這些問題:
- 遞歸對象 (直接或間接包含對自身引用的復合對象) 可能會導致遞歸循環。
- 由于深拷貝會復制所有內容,因此可能會過多復制(例如本應該在副本之間共享的數據)。
四、引用傳遞與值傳遞
可變對象為引用傳遞,不可變對象為值傳遞。(函數傳值)
1,值傳遞: 簡單來說 對于函數輸入的參數對象,函數執行中首先生成對象的一個副本,并在執行過程中對副本進行操作。執行結束后對象不發生改變
即在堆棧中開辟了內存空間以存放由主調函數放進來的實參的值,從而成為了實參的一個副本。值傳遞的特點是被調函數對形式參數的任何操作都是作為局部變量進行,不會影響主調函數的實參變量的值。(被調函數新開辟內存空間存放的是實參的副本值)
值傳遞不會改變原來函數的值,
def Change(b):b += 2 傳遞進來的為不可變對象,為值傳遞 相當于相同值的一個副本print(id(b)) print (b)returna = 2 print(id(a)) Change(a) print (a) print(id(a))輸出為
140724617470832 a本來地址 140724617470896 值傳遞b的地址 4 在函數中為4 2 a本身還是2 140724617470832 a地址也沒有改變4.2. 引用傳遞
當傳遞列表或者字典時,如果改變引用的值,就修改了原始的對象。(被調函數新開辟內存空間存放的是實參的地址)
def Change(str1):str1[1] ="changed " 此處修改就是直接修改string的值returnstring = ['hello world',2,3] print (string) Change(string) print (string)函數的實參使用可變類型數據時,在函數內部對形參進行數據操作,實參將發生改變
函數的實參使用不可變類型數據時,在函數內部對形參進行數據操作,實參將不會發生改變
總結
以上是生活随笔為你收集整理的python中浅拷贝与深拷贝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: opencv画矩形以及在图像上放文字
- 下一篇: python中常见的异常