欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python變量的賦值、淺拷貝和深拷貝詳解

 更新時間:2023年11月04日 10:04:09   作者:驚瑟  
這篇文章主要介紹了Python變量的賦值、淺拷貝和深拷貝詳解,python中為聲明一個變量有三種方法:賦值、淺拷貝、深拷貝,相信每個pythoner或多或少都知道他們之間的區(qū)別,但在某些點上,還是會踩坑,這篇文章記錄下所有關于這三者區(qū)別的疑問,需要的朋友可以參考下

前言

python中為聲明一個變量有三種方法:賦值、淺拷貝(shadow copy)、深拷貝(deep copy),相信每個pythoner或多或少都知道他們之間的區(qū)別,但在某些點上,還是會踩坑,這篇文章記錄下所有關于這三者區(qū)別的疑問。

對比

在理解以上幾個概念區(qū)別之前需要明確以下問題:

  • 賦值傳遞的是原始對象的地址
  • 函數(shù)傳遞形參也是傳遞地址,該地址指向原始對象,多進程的task函數(shù)除外,多進程中task函數(shù)的形參和原始對象是完全不同的兩個對象,類似深拷貝(進程間內(nèi)存獨立)
  • 淺拷貝,除了顯式地調(diào)用copy庫,還可以使用如切片、list()、dict()等函數(shù)達到淺拷貝的效果(下面會給例子)。
  • 當我們討論python中的拷貝時,默認針對的是可變對象,因為對于不可變對象來講,拷貝是沒有意義的,python解釋器在啟動時就將不可變對象放在內(nèi)存池中了,它在內(nèi)存的位置在解釋器終止之前不會變。假設我們通過賦值、淺拷貝、深拷貝得到了一個新的對象,那么與原始對象相比,有以下結論:
/賦值淺拷貝深拷貝
id是否變化×??
修改對象本身是否互相影響?××
修改嵌套對象是否互相影響??×

具體例子

a = ['a', 1, [1,2]]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)

print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')
print(f'c is: {c} , id is: {id(c)}')
print(f'd is: vvxyksv9kd , id is: {id(d)}')

輸出:

a is: ['a', 1, [1, 2]] , id is: 140211144620672
b is: ['a', 1, [1, 2]] , id is: 140211144620672
c is: ['a', 1, [1, 2]] , id is: 140211144622016
d is: ['a', 1, [1, 2]] , id is: 140211144620992

可以看出,賦值得到的新對象id與原始對象id相同,拷貝得到的新對象id與原始對象不同。

# 對對象本身進行修改,即“最外層”
a.append(2)

print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')
print(f'c is: {c} , id is: {id(c)}')
print(f'd is: vvxyksv9kd , id is: {id(d)}')

輸出:

a is: ['a', 1, [1, 2], 2] , id is: 140211144620672
b is: ['a', 1, [1, 2], 2] , id is: 140211144620672
c is: ['a', 1, [1, 2]] , id is: 140211144622016
d is: ['a', 1, [1, 2]] , id is: 140211144620992

可以看出,修改對象本身對拷貝對象沒有影響。 再修改嵌套對象:

# 修改嵌套對象
a[2].append(3)

print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')
print(f'c is: {c} , id is: {id(c)}')
print(f'd is: vvxyksv9kd , id is: {id(d)}')

輸出:

a is: ['a', 1, [1, 2, 3], 2] , id is: 140211144620672
b is: ['a', 1, [1, 2, 3], 2] , id is: 140211144620672
c is: ['a', 1, [1, 2, 3]] , id is: 140211144622016
d is: ['a', 1, [1, 2]] , id is: 140211144620992

可以看出,修改嵌套對象,對淺拷貝對象有影響,對深拷貝對象無影響。 再看下不可變對象1的id:

print(f'1 id in a is {id(a[1])}')
print(f'1 id in b is {id(b[1])}')
print(f'1 id in c is {id(c[1])}')
print(f'1 id in d is {id(d[1])}')

輸出:

1 id in a is 140279957373168
1 id in b is 140279957373168
1 id in c is 140279957373168
1 id in d is 140279957373168 

可以看出,所有對象的不可變對象指向了同一個位置,事實上,即便在同一個對象中相同的不可變對象也是指向同一個位置:

print(f'a is {a}')
print(f'{id(a[1])}, {id(a[2][0])}')

輸出:

a is ['a', 1, [1, 2, 3], 2]
140168057503984, 140168057503984

除了顯示地使用copy.copy()獲得一個淺拷貝對象,list()、dict()等對象工廠也可以獲得一個淺拷貝對象:

a = ['a', 1, [1,2]]
b = list(a)
print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')

a[2].append(3)
print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')

輸出:

a is: ['a', 1, [1, 2]] , id is: 139717765197952
b is: ['a', 1, [1, 2]] , id is: 139718287865280
a is: ['a', 1, [1, 2, 3]] , id is: 139717765197952
b is: ['a', 1, [1, 2, 3]] , id is: 139718287865280

可以看出,a與b的id不同,但修改嵌套對象會互相影響,所以b是a的淺拷貝對象。

切片也類似,是一個淺拷貝對象:

a = ['a', 1, [1,2]]
b = a[-1:]
print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')

a[2].append(3)
print(f'a is: {a} , id is: {id(a)}')
print(f'b is:  , id is: {id(b)}')

輸出:

a is: ['a', 1, [1, 2]] , id is: 140294636448256
b is: [[1, 2]] , id is: 140294636449408
a is: ['a', 1, [1, 2, 3]] , id is: 140294636448256
b is: [[1, 2, 3]] , id is: 140294636449408

到此這篇關于Python變量的賦值、淺拷貝和深拷貝詳解的文章就介紹到這了,更多相關Python賦值、淺拷貝和深拷貝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論