說到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對於不可變型別...