流暢的python 深拷貝,淺拷貝

2021-08-03 03:29:30 字數 2131 閱讀 2901

說到python中的物件引用問題,還得看看is和==的區別:

>>> a = [1,2,3,4]

>>> b = [1,2,3,4]

>>> a == b

true

>>> a is b

false

可以看見a和b中的數值都是一樣的,但是==與is的結果卻不是一樣的,這是因為python中==比較的是a和b的數值相等,is比較物件的標識是否相等。所以在python中我們經常會使用==來比較物件的數值時候相等, 判斷物件繫結的值時候是none, 最好使用is。這裡面有乙個坑,一些新手經常犯的錯誤,空字串,空列表,空字典,他們的都等於false,但是他們都不是(不等於)none,所以在判斷乙個字串,列表,字典是否為空時, 不要用none來做比較,因為這些變數無論是從物件標識,數值都與none不相等。

我們平常是用的物件複製一般都是淺拷貝。copy模組為我們提供了copy(淺拷貝),deepcopy(深拷貝)函式。

什麼是淺拷貝:

淺拷貝就是將拷貝的物件引用拷貝乙份,拷貝物件指向的是被拷貝物件的數值,簡單的說就是,在原有數值上面再新增的乙份引用。

>>> a =1

>>> b =a

>>> id(a)

4297636352

>>> id(b)

4297636352

什麼是深拷貝:

深拷貝就是拷貝物件對被拷貝物件數值上覆制乙份,然後新建乙個物件,這個新的物件數值,物件標識都是和被拷貝物件相等的,

>>> 

import copy

>>> a = [1,2,3]

>>> b = copy.deepcopy(a)

>>> b

[1,2,3]

>>> a

[1,2,3]

>>> a == b

true

>>> a is b

true

>>> id(a)

4297636352

>>> id(b)

4297636352

>>> a

[1,2,3,0]

>>> b

[1,2,3]

>>> b

[1, 2, 3, 9]

>>> a

[1, 2, 3, 0]

基於這種現象,所以我們應該特別注意函式在使用可變引數

作為預設引數,如不注意就會出現下面這種情況:

>>> 

defa

(x = ):

... print(x)

...

>>> a()

[0]>>> a()

[0, 0]

>>> a()

[0, 0, 0]

為了避免這種情況我們應該避免使用可變物件作為函式預設引數:

>>> 

defa

(x = none):

...

if x is

none:

... x =

...

else:

... print(x)

...

>>> a()

>>> a()

同時建立類初始化傳參也是使用淺拷貝來傳遞的,這樣就會出現這種情況:

>>> 

class

a:...

def__init__

(self, name):

... self.name = name

...

defprintf

(self):

... print(self.name)

...

>>> x = [1,2,3,4]

>>> a = a(x)

>>> a.printf()

[1, 2, 3, 4]

>>> a.printf()

[1, 2, 3, 4, 5]

在傳入的引數改變的時候,類裡面的變數的值頁跟著改變了,這種情況時最懶發現的。

python 淺拷貝 深拷貝

直接賦值 其實就是物件的引用 別名 淺拷貝 copy 拷貝父物件,不會拷貝物件的內部的子物件。深拷貝 deepcopy copy 模組的 deepcopy 方法,完全拷貝了父物件及其子物件。usr bin python import copy a 1,2,3,4,a b 原始物件 b a 賦值,傳物...

python深拷貝 淺拷貝

在python中,物件賦值實際上是物件的引用。當建立乙個物件,然後把它賦給另乙個變數的時候,python並沒有拷貝這個物件,而只是拷貝了這個物件的引用 一般有三種方法,alist 1,2,3,a b 1 直接賦值,傳遞物件的引用而已,原始列表改變,被賦值的b也會做相同的改變 alist 1,2,3,...

python 深拷貝 淺拷貝

淺拷貝是對於乙個物件的頂層拷貝 通俗的理解是 拷貝了引用,並沒有拷貝內容 深拷貝是對於乙個物件所有層次的拷貝 遞迴 拷貝字典 值相當於鍵的引用 所以copy.copy 為淺拷貝 淺拷貝對不可變型別和可變型別的copy不同 copy.copy對於可變型別,會進行淺拷貝 copy.copy對於不可變型別...